name: Added compare and comparison operators. Remove breadthFirstLess
Change-Id: Ie940733ac8460636ee6087f03e78d545373a26d9
diff --git a/include/ndn-cpp-dev/name.hpp b/include/ndn-cpp-dev/name.hpp
index c4e7e5c..ebac18f 100644
--- a/include/ndn-cpp-dev/name.hpp
+++ b/include/ndn-cpp-dev/name.hpp
@@ -649,6 +649,22 @@
return components_[size() + i];
}
+ /**
+ * Compare this to the other Name using NDN canonical ordering. If the first components of each name are not equal,
+ * this returns -1 if the first comes before the second using the NDN canonical ordering for name components, or 1 if it comes after.
+ * If they are equal, this compares the second components of each name, etc. If both names are the same up to
+ * the size of the shorter name, this returns -1 if the first name is shorter than the second or 1 if it is longer.
+ * For example, if you std::sort gives: /a/b/d /a/b/cc /c /c/a /bb . This is intuitive because all names
+ * with the prefix /a are next to each other. But it may be also be counter-intuitive because /c comes before /bb
+ * according to NDN canonical ordering since it is shorter.
+ * @param other The other Name to compare with.
+ * @return 0 If they compare equal, -1 if *this comes before other in the canonical ordering, or
+ * 1 if *this comes after other in the canonical ordering.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ int
+ compare(const Name& other) const;
const Component&
operator [] (int i) const
@@ -681,30 +697,42 @@
*/
bool
operator != (const Name &name) const { return !equals(name); }
-
- /**
- * Compare two names for "less than" using breadth first. If the first components of each name are not equal,
- * this returns true if the first comes before the second using the NDN canonical ordering for name components.
- * If they are equal, this compares the second components of each name, etc. If both names are the same up to
- * the size of the shorter name, this returns true if the first name is shorter than the second. For example, if you
- * use breadthFirstLess in std::sort, it gives: /a/b/d /a/b/cc /c /c/a /bb . This is intuitive because all names
- * with the prefix /a are next to each other. But it may be also be counter-intuitive because /c comes before /bb
- * according to NDN canonical ordering since it is shorter. Note: We don't define this directly as the Name
- * less than operation because there are other valid ways to sort names.
- * @param name1 The first name to compare.
- * @param name2 The second name to compare.
- * @return True if the first name is less than the second using breadth first comparison.
- */
- static bool
- breadthFirstLess(const Name& name1, const Name& name2);
/**
- * Name::BreadthFirstLess is a function object which calls breadthFirstLess, for use as the "less" operator in map, etc.
- * For example, you can use Name as the key type in a map as follows: map<Name, int, Name::BreadthFirstLess>.
+ * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
+ * @param other The other Name to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
*/
- struct BreadthFirstLess {
- bool operator() (const Name& name1, const Name& name2) const { return breadthFirstLess(name1, name2); }
- };
+ bool
+ operator <= (const Name& other) const { return compare(other) <= 0; }
+
+ /**
+ * Return true if this is less than the other Name in the NDN canonical ordering.
+ * @param other The other Name to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator < (const Name& other) const { return compare(other) < 0; }
+
+ /**
+ * Return true if this is less than or equal to the other Name in the NDN canonical ordering.
+ * @param other The other Name to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator >= (const Name& other) const { return compare(other) >= 0; }
+
+ /**
+ * Return true if this is greater than the other Name in the NDN canonical ordering.
+ * @param other The other Name to compare with.
+ *
+ * @see http://named-data.net/doc/0.2/technical/CanonicalOrder.html
+ */
+ bool
+ operator > (const Name& other) const { return compare(other) > 0; }
//
// Iterator interface to name components.
diff --git a/src/name.cpp b/src/name.cpp
index 6cd8e0d..7a3d171 100644
--- a/src/name.cpp
+++ b/src/name.cpp
@@ -298,20 +298,26 @@
}
}
-bool
-Name::breadthFirstLess(const Name& name1, const Name& name2)
+int
+Name::compare(const Name& other) const
{
- for (size_t i = 0; i < name1.size() && i < name2.size(); ++i) {
- if (name1[i] == name2[i])
+ for (size_t i = 0; i < size() && i < other.size(); ++i) {
+ int comparison = components_[i].compare(other.components_[i]);
+ if (comparison == 0)
// The components at this index are equal, so check the next components.
continue;
// Otherwise, the result is based on the components at this index.
- return name1[i] < name2[i];
+ return comparison;
}
- // The components up to min(name1.size(), name2.size()) are equal, so sort on the shorter name.
- return name1.size() < name2.size();
+ // The components up to min(this.size(), other.size()) are equal, so the shorter name is less.
+ if (size() < other.size())
+ return -1;
+ else if (size() > other.size())
+ return 1;
+ else
+ return 0;
}
std::ostream&
@@ -370,6 +376,4 @@
append(i->value(), i->value_size());
}
}
-
-
}