|
@@ -28,35 +28,89 @@ void BeatSequence::expand(BeatIndex factor)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void BeatSequence::print(std::ostream& stream) const
|
|
|
+void BeatSequence::reduce(BeatIndex factor)
|
|
|
+{
|
|
|
+ reduce(factor, 0, 0);
|
|
|
+}
|
|
|
+
|
|
|
+void BeatSequence::reduce(BeatIndex factor, ReducationConflictCallback conflictCallback, void* conflictCallbackData)
|
|
|
{
|
|
|
- stream << "beat sequence:\n";
|
|
|
+ if(factor < 1) {
|
|
|
+ throw "factor may not be less than 1.";
|
|
|
+ }
|
|
|
|
|
|
+ if(conflictCallback != 0) {
|
|
|
+ for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
|
|
|
+ if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
|
|
|
+ conflictCallback(*this, factor, beatIndex, conflictCallbackData);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
|
|
|
+ if(beatIndex % factor != 0 && at(beatIndex).size() > 0) {
|
|
|
+ throw new UnresolvedBeatSequenceReducationConflict(beatIndex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ BeatIndex targetSize = (size() + factor - 1) / factor;
|
|
|
+ for(BeatIndex targetIndex = 0; targetIndex < targetSize; targetIndex++) {
|
|
|
+ BeatIndex sourceIndex = targetIndex * factor;
|
|
|
+ at(sourceIndex).swap(at(targetIndex));
|
|
|
+ }
|
|
|
+ resize(targetSize);
|
|
|
+}
|
|
|
+
|
|
|
+void BeatSequence::print(std::ostream& stream) const
|
|
|
+{
|
|
|
+ if(size() == 0) {
|
|
|
+ stream << "beat sequence of length 0\n";
|
|
|
+ } else {
|
|
|
+ stream << "beat sequence:\n";
|
|
|
|
|
|
- std::stringstream beatLabelStream;
|
|
|
- beatLabelStream << "beat #" << beatIndex << ": ";
|
|
|
- std::string beatLabel = beatLabelStream.str();
|
|
|
- stream << beatLabel;
|
|
|
+ for(BeatIndex beatIndex = 0; beatIndex < size(); beatIndex++) {
|
|
|
|
|
|
- std::string spacer(beatLabel.size(), ' ');
|
|
|
+ std::stringstream beatLabelStream;
|
|
|
+ beatLabelStream << "beat #" << beatIndex << ": ";
|
|
|
+ std::string beatLabel = beatLabelStream.str();
|
|
|
+ stream << beatLabel;
|
|
|
|
|
|
- const MessageList& beat = at(beatIndex);
|
|
|
- if(beat.size() == 0) {
|
|
|
- stream << "no message" << "\n";
|
|
|
- } else {
|
|
|
- for(MessageList::const_iterator msg_it = beat.begin(); msg_it != beat.end(); msg_it++) {
|
|
|
- if(msg_it != beat.begin()) {
|
|
|
- stream << spacer;
|
|
|
+ std::string spacer(beatLabel.size(), ' ');
|
|
|
+
|
|
|
+ const MessageList& beat = at(beatIndex);
|
|
|
+ if(beat.size() == 0) {
|
|
|
+ stream << "no message" << "\n";
|
|
|
+ } else {
|
|
|
+ for(MessageList::const_iterator msg_it = beat.begin(); msg_it != beat.end(); msg_it++) {
|
|
|
+ if(msg_it != beat.begin()) {
|
|
|
+ stream << spacer;
|
|
|
+ }
|
|
|
+ (*msg_it)->print(stream);
|
|
|
}
|
|
|
- (*msg_it)->print(stream);
|
|
|
}
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
stream << "\n";
|
|
|
stream.flush();
|
|
|
}
|
|
|
|
|
|
+UnresolvedBeatSequenceReducationConflict::UnresolvedBeatSequenceReducationConflict(BeatSequence::BeatIndex beatIndex)
|
|
|
+ : parent("unresolved beat sequence reducation conflict"), beatIndex(beatIndex)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+const char* UnresolvedBeatSequenceReducationConflict::what() const throw()
|
|
|
+{
|
|
|
+ std::stringstream info;
|
|
|
+ info << parent::what() << " at beat #" << getBeatIndex();
|
|
|
+ return info.str().c_str();
|
|
|
+}
|
|
|
+
|
|
|
+BeatSequence::BeatIndex UnresolvedBeatSequenceReducationConflict::getBeatIndex() const
|
|
|
+{
|
|
|
+ return beatIndex;
|
|
|
+}
|
|
|
+
|
|
|
} // namepsace
|