+XMLNode*
+ChanMapping::state(const std::string& name) const
+{
+ XMLNode* node = new XMLNode (name);
+ 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) {
+ XMLNode* n = new XMLNode(X_(state_node_name));
+ n->add_property("type", tm->first.to_string());
+ n->add_property("from", i->first);
+ n->add_property("to", i->second);
+ node->add_child_nocopy(*n);
+ }
+ }
+ return node;
+}
+
+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;
+}
+
+uint32_t
+ChanMapping::n_total () const
+{
+ // fast version of count().n_total();
+ uint32_t rv = 0;
+ const Mappings& mp (mappings());
+ for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+ rv += tm->second.size ();
+ }
+ return rv;
+}
+
+ChanCount
+ChanMapping::count () const
+{
+ ChanCount rv;
+ const Mappings& mp (mappings());
+ for (Mappings::const_iterator tm = mp.begin(); tm != mp.end(); ++tm) {
+ rv.set (tm->first, tm->second.size ());
+ }
+ return rv;
+}
+
+
+