summaryrefslogtreecommitdiff
path: root/boost/safe_numerics/checked_result.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/safe_numerics/checked_result.hpp')
-rw-r--r--boost/safe_numerics/checked_result.hpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/boost/safe_numerics/checked_result.hpp b/boost/safe_numerics/checked_result.hpp
new file mode 100644
index 0000000000..55efca082a
--- /dev/null
+++ b/boost/safe_numerics/checked_result.hpp
@@ -0,0 +1,97 @@
+#ifndef BOOST_NUMERIC_CHECKED_RESULT
+#define BOOST_NUMERIC_CHECKED_RESULT
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// Copyright (c) 2012 Robert Ramey
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// contains operations for doing checked aritmetic on NATIVE
+// C++ types.
+#include <cassert>
+#include <type_traits> // is_convertible
+#include "exception.hpp"
+
+namespace boost {
+namespace safe_numerics {
+
+template<typename R>
+struct checked_result {
+ const safe_numerics_error m_e;
+ const union {
+ R m_r;
+ char const * m_msg;
+ };
+
+ // don't permit construction without initial value;
+ checked_result() = delete;
+
+ constexpr /*explicit*/ checked_result(const R & r) :
+ m_e(safe_numerics_error::success),
+ m_r(r)
+ {}
+ #if 0
+ template<typename T>
+ constexpr /*explicit*/ checked_result(const T & t) :
+ m_e(safe_numerics_error::success),
+ m_r(t)
+ {}
+ #endif
+ constexpr /*explicit*/ checked_result(
+ safe_numerics_error e,
+ const char * msg = ""
+ ) :
+ m_e(e),
+ m_msg(msg)
+ {
+ assert(m_e != safe_numerics_error::success);
+ }
+ // permit construct from another checked result type
+ template<typename T>
+ constexpr /*explicit*/ checked_result(const checked_result<T> & t) :
+ m_e(t.m_e)
+ {
+ static_assert(
+ std::is_convertible<T, R>::value,
+ "T must be convertible to R"
+ );
+ if(safe_numerics_error::success == t.m_e)
+ m_r = t.m_r;
+ else
+ m_msg = t.m_msg;
+ }
+ constexpr bool exception() const {
+ return m_e != safe_numerics_error::success;
+ }
+
+ // accesors
+ constexpr operator R() const {
+ // don't assert here. Let the library catch these errors
+ assert(! exception());
+ return m_r;
+ }
+
+ constexpr operator safe_numerics_error () const {
+ // note that this is a legitimate operation even when
+ // the operation was successful - it will return success
+ return m_e;
+ }
+ constexpr operator const char *() const {
+ assert(exception());
+ return m_msg;
+ }
+
+ // disallow assignment
+ checked_result & operator=(const checked_result &) = delete;
+};
+
+} // safe_numerics
+} // boost
+
+#endif // BOOST_NUMERIC_CHECKED_RESULT