abort if configuration fails
[ardour.git] / libs / ardour / chan_mapping.cc
index 5c5bb17de67a292c3094eb4584dbf25e84779603..0ca79af505d1f69ccf58b1008e8f77c84ea0be24 100644 (file)
@@ -40,20 +40,30 @@ ChanMapping::ChanMapping(ChanCount identity)
        }
 }
 
+ChanMapping::ChanMapping (const ChanMapping& other )
+{
+       const ChanMapping::Mappings& mp (other.mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       set (tm->first, i->first, i->second);
+               }
+       }
+}
+
 uint32_t
-ChanMapping::get(DataType t, uint32_t from, bool* valid)
+ChanMapping::get(DataType t, uint32_t from, bool* valid) const
 {
-       Mappings::iterator tm = _mappings.find(t);
+       Mappings::const_iterator tm = _mappings.find(t);
        if (tm == _mappings.end()) {
-               *valid = false;
+               if (valid) { *valid = false; }
                return -1;
        }
-       TypeMapping::iterator m = tm->second.find(from);
+       TypeMapping::const_iterator m = tm->second.find(from);
        if (m == tm->second.end()) {
-               *valid = false;
+               if (valid) { *valid = false; }
                return -1;
        }
-       *valid = true;
+       if (valid) { *valid = true; }
        return m->second;
 }
 
@@ -61,22 +71,33 @@ void
 ChanMapping::set(DataType t, uint32_t from, uint32_t to)
 {
        assert(t != DataType::NIL);
-       Mappings::iterator tm = _mappings.find(t);
+       Mappings::iterator tm = _mappings.find (t);
        if (tm == _mappings.end()) {
                tm = _mappings.insert(std::make_pair(t, TypeMapping())).first;
        }
        tm->second.insert(std::make_pair(from, to));
 }
 
+void
+ChanMapping::unset(DataType t, uint32_t from)
+{
+       assert(t != DataType::NIL);
+       Mappings::iterator tm = _mappings.find (t);
+       if (tm == _mappings.end()) {
+               return;
+       }
+       tm->second.erase(from);
+}
+
 /** Offset the 'from' field of every mapping for type @a t by @a delta */
 void
 ChanMapping::offset_from(DataType t, int32_t delta)
 {
        Mappings::iterator tm = _mappings.find(t);
-       if (tm != _mappings.end()) {
+       if (tm != _mappings.end ()) {
                TypeMapping new_map;
                for (TypeMapping::iterator m = tm->second.begin(); m != tm->second.end(); ++m) {
-                       new_map.insert(make_pair(m->first + delta, m->second));
+                       new_map.insert (make_pair (m->first + delta, m->second));
                }
                tm->second = new_map;
        }
@@ -94,12 +115,61 @@ ChanMapping::offset_to(DataType t, int32_t delta)
        }
 }
 
+bool
+ChanMapping::is_subset (const ChanMapping& superset) const
+{
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       bool valid;
+                       if (i->second != superset.get (tm->first, i->first, &valid)) {
+                               return false;
+                       }
+                       if (!valid) {
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
+
+bool
+ChanMapping::is_monotonic () const
+{
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               uint32_t prev = UINT32_MAX;
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       // set keys are strictly weak ordered
+                       if (i->first < i->second || i->second == prev) {
+                               return false;
+                       }
+                       prev = i->second;
+               }
+       }
+       return true;
+}
+
+bool
+ChanMapping::is_identity (ChanCount offset) const
+{
+       const Mappings& mp (mappings());
+       for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+               for (TypeMapping::const_iterator i = tm->second.begin(); i != tm->second.end(); ++i) {
+                       if (i->first + offset.get (tm->first) != i->second) {
+                               return false;
+                       }
+               }
+       }
+       return true;
+}
+
 } // namespace ARDOUR
 
 std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
 {
-       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = cm.mappings().begin();
-                       tm != cm.mappings().end(); ++tm) {
+       const ARDOUR::ChanMapping::Mappings& mp (cm.mappings());
+       for (ARDOUR::ChanMapping::Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
                o << tm->first.to_string() << endl;
                for (ARDOUR::ChanMapping::TypeMapping::const_iterator i = tm->second.begin();
                                i != tm->second.end(); ++i) {
@@ -109,4 +179,3 @@ std::ostream& operator<<(std::ostream& o, const ARDOUR::ChanMapping& cm)
 
        return o;
 }
-