summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-10-18 22:07:57 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-10-18 22:07:57 +0100
commit2f7fc20abf11a28011c828449142fb0df1ab858c (patch)
treeca3fde5feaa640ea3d4d88d6847c3a45344427e3
parentAdd file handle constructor that accepts mode. (diff)
downloadlibadhocutil-2f7fc20abf11a28011c828449142fb0df1ab858c.tar.bz2
libadhocutil-2f7fc20abf11a28011c828449142fb0df1ab858c.tar.xz
libadhocutil-2f7fc20abf11a28011c828449142fb0df1ab858c.zip
Add operator/ for resolving optional things to a final thing
-rw-r--r--libadhocutil/optionals.h30
-rw-r--r--libadhocutil/unittests/Jamfile.jam8
-rw-r--r--libadhocutil/unittests/testOptionals.cpp46
3 files changed, 84 insertions, 0 deletions
diff --git a/libadhocutil/optionals.h b/libadhocutil/optionals.h
new file mode 100644
index 0000000..f4d6b1a
--- /dev/null
+++ b/libadhocutil/optionals.h
@@ -0,0 +1,30 @@
+#ifndef ADHOCUTIL_OPTIONALS_H
+#define ADHOCUTIL_OPTIONALS_H
+
+#include <type_traits>
+
+namespace AdHoc {
+ template <typename A, typename B>
+ auto
+ operator/(const A & a, const B & b) -> typename std::enable_if<
+ std::is_constructible<bool, A>::value &&
+ !std::is_pointer<B>::value &&
+ std::is_convertible<decltype(*a), B>::value,
+ decltype(a ? *a : b)>::type
+ {
+ return (a ? *a : b);
+ }
+
+ template <typename A, typename B>
+ auto
+ operator/(const A & a, const B & b) -> typename std::enable_if<
+ std::is_constructible<bool, A>::value &&
+ std::is_pointer<B>::value,
+ decltype(a ? &*a : b)>::type
+ {
+ return (a ? &*a : b);
+ }
+}
+
+#endif
+
diff --git a/libadhocutil/unittests/Jamfile.jam b/libadhocutil/unittests/Jamfile.jam
index bf86e9c..5072f39 100644
--- a/libadhocutil/unittests/Jamfile.jam
+++ b/libadhocutil/unittests/Jamfile.jam
@@ -261,3 +261,11 @@ run
<library>boost_filesystem
;
+run
+ testOptionals.cpp
+ : : :
+ <define>BOOST_TEST_DYN_LINK
+ <library>..//adhocutil
+ <library>boost_utf
+ ;
+
diff --git a/libadhocutil/unittests/testOptionals.cpp b/libadhocutil/unittests/testOptionals.cpp
new file mode 100644
index 0000000..7e5b4b1
--- /dev/null
+++ b/libadhocutil/unittests/testOptionals.cpp
@@ -0,0 +1,46 @@
+#define BOOST_TEST_MODULE Buffer
+#include <boost/test/unit_test.hpp>
+
+#include <optionals.h>
+#include <boost/optional.hpp>
+#include <IceUtil/Exception.h>
+#include <IceUtil/Optional.h>
+
+using namespace AdHoc;
+
+BOOST_AUTO_TEST_CASE ( general )
+{
+ boost::optional<int> x;
+ boost::optional<double> y = 2.3;
+ IceUtil::Optional<float> ix;
+ IceUtil::Optional<short> iy = 4;
+ std::string * p = nullptr;
+ std::string * q = new std::string("str");
+ boost::optional<std::string> r;
+ IceUtil::Optional<std::string> s;
+
+ bool b(p);
+ BOOST_REQUIRE_EQUAL(false, b);
+ auto a1 = x / y;
+ BOOST_REQUIRE(a1);
+ BOOST_REQUIRE_EQUAL(2.3, *a1);
+ auto a2 = x / 10;
+ BOOST_REQUIRE_EQUAL(10, a2);
+ auto a3 = ix / 11;
+ BOOST_REQUIRE_EQUAL(11, a3);
+ auto a4 = iy / 11;
+ BOOST_REQUIRE_EQUAL(4, a4);
+
+ auto s1 = p / s / r;
+ BOOST_REQUIRE(!s1);
+ auto s2 = q / s / r;
+ BOOST_REQUIRE(s2);
+ BOOST_REQUIRE_EQUAL("str", *s2);
+
+ auto p1 = r / q;
+ BOOST_REQUIRE(p1);
+ BOOST_REQUIRE_EQUAL("str", *p1);
+
+ delete q;
+}
+