summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libadhocutil/safeMapFind.h60
-rw-r--r--libadhocutil/unittests/Jamfile.jam10
-rw-r--r--libadhocutil/unittests/testMapFinds.cpp57
3 files changed, 127 insertions, 0 deletions
diff --git a/libadhocutil/safeMapFind.h b/libadhocutil/safeMapFind.h
new file mode 100644
index 0000000..9b2823a
--- /dev/null
+++ b/libadhocutil/safeMapFind.h
@@ -0,0 +1,60 @@
+#ifndef ADHOCUTIL_SAFEMAPFIND_H
+#define ADHOCUTIL_SAFEMAPFIND_H
+
+/*
+ * Find the key and return the iterator to the pair,
+ * or throw Ex(key) if not found.
+ */
+template <class Ex, class Map>
+typename Map::const_iterator
+safeMapFind(const Map & map, const typename Map::key_type & key)
+{
+ typename Map::const_iterator i = map.find(key);
+ if (i == map.end()) {
+ throw Ex(key);
+ }
+ return i;
+}
+
+/*
+ * Find the key and return the mapped value
+ * or the provided default value if not found.
+ */
+template <class Map>
+typename Map::mapped_type
+defaultMapLookup(const Map & map, const typename Map::key_type & key, const typename Map::mapped_type & def = typename Map::mapped_type())
+{
+ typename Map::const_iterator i = map.find(key);
+ if (i == map.end()) {
+ return def;
+ }
+ return i->second;
+}
+
+/*
+ * Find the key and return the mapped value
+ * or throw Ex(key) if not found.
+ */
+template <class Ex, class Map>
+const typename Map::mapped_type &
+safeMapLookup(const Map & map, const typename Map::key_type & key)
+{
+ typename Map::const_iterator i = map.find(key);
+ if (i == map.end()) {
+ throw Ex(key);
+ }
+ return i->second;
+}
+
+/*
+ * Simple search, true if found, false otherwise
+ */
+template <class Cont>
+bool
+containerContains(const Cont & c, const typename Cont::value_type & v)
+{
+ return (std::find(c.begin(), c.end(), v) != c.end());
+}
+
+#endif
+
diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam
index de5336e..c8abcb9 100644
--- a/libadhocutil/unittests/Jamfile.jam
+++ b/libadhocutil/unittests/Jamfile.jam
@@ -53,3 +53,13 @@ run
testProcessPipes
;
+run
+ testMapFinds.cpp
+ : : :
+ <define>BOOST_TEST_DYN_LINK
+ <library>..//adhocutil
+ <library>boost_utf
+ :
+ testMapFinds
+ ;
+
diff --git a/libadhocutil/unittests/testMapFinds.cpp b/libadhocutil/unittests/testMapFinds.cpp
new file mode 100644
index 0000000..c0b7c5e
--- /dev/null
+++ b/libadhocutil/unittests/testMapFinds.cpp
@@ -0,0 +1,57 @@
+#define BOOST_TEST_MODULE MapFinds
+#include <boost/test/unit_test.hpp>
+
+#include <boost/lexical_cast.hpp>
+#include "safeMapFind.h"
+#include <stdexcept>
+#include <string>
+#include <map>
+
+class NotFound : std::runtime_error {
+ public:
+ NotFound(int key) :
+ std::runtime_error(boost::lexical_cast<std::string>("Key not found: %d", key))
+ {
+ }
+};
+
+const std::map<int, std::string> sample {
+ { 1, "one" },
+ { 2, "two" },
+ { 4, "four" },
+ { 8, "eight" },
+ { 16, "sixteen" }
+};
+
+BOOST_AUTO_TEST_CASE ( testSafeMapFind )
+{
+ BOOST_REQUIRE_EQUAL(safeMapFind<NotFound>(sample, 1)->first, 1);
+ BOOST_REQUIRE_EQUAL(safeMapFind<NotFound>(sample, 1)->second, "one");
+ BOOST_REQUIRE_EQUAL(safeMapFind<NotFound>(sample, 4)->first, 4);
+ BOOST_REQUIRE_EQUAL(safeMapFind<NotFound>(sample, 4)->second, "four");
+ BOOST_REQUIRE_THROW(safeMapFind<NotFound>(sample, 5), NotFound);
+}
+
+BOOST_AUTO_TEST_CASE ( testDefaultMapLookup )
+{
+ BOOST_REQUIRE_EQUAL(defaultMapLookup(sample, 1), "one");
+ BOOST_REQUIRE_EQUAL(defaultMapLookup(sample, 4), "four");
+ BOOST_REQUIRE_EQUAL(defaultMapLookup(sample, 5), std::string());
+ BOOST_REQUIRE_EQUAL(defaultMapLookup(sample, 5, "default"), "default");
+}
+
+BOOST_AUTO_TEST_CASE ( testSafeMapLookup )
+{
+ BOOST_REQUIRE_EQUAL(safeMapLookup<NotFound>(sample, 1), "one");
+ BOOST_REQUIRE_EQUAL(safeMapLookup<NotFound>(sample, 4), "four");
+ BOOST_REQUIRE_THROW(safeMapLookup<NotFound>(sample, 5), NotFound);
+}
+
+BOOST_AUTO_TEST_CASE ( testContainerContains )
+{
+ BOOST_REQUIRE_EQUAL(true, containerContains(sample, {1, "one"}));
+ BOOST_REQUIRE_EQUAL(false, containerContains(sample, {2, "one"}));
+ BOOST_REQUIRE_EQUAL(false, containerContains(sample, {1, "two"}));
+ BOOST_REQUIRE_EQUAL(true, containerContains(sample, {2, "two"}));
+}
+