1#ifndef BOOST_NUMERIC_CHECKED_RESULT
2#define BOOST_NUMERIC_CHECKED_RESULT
3
4// Copyright (c) 2012 Robert Ramey
5//
6// Distributed under the Boost Software License, Version 1.0. (See
7// accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
10// contains operations for doing checked aritmetic on NATIVE
11// C++ types.
12#include <cassert>
13#include <type_traits> // is_convertible
14#include "exception.hpp"
15
16namespace boost {
17namespace safe_numerics {
18
19template<typename R>
20struct checked_result {
21 const safe_numerics_error m_e;
22 union contents {
23 R m_r;
24 char const * const m_msg;
25 // contstructors for different types
26 constexpr contents(const R & r) noexcept : m_r(r){}
27 constexpr contents(char const * msg) noexcept : m_msg(msg) {}
28 constexpr operator R () noexcept {
29 return m_r;
30 }
31 constexpr operator char const * () noexcept {
32 return m_msg;
33 }
34 };
35 contents m_contents;
36
37 // don't permit construction without initial value;
38 checked_result() = delete;
39 checked_result(const checked_result & r) = default;
40 checked_result(checked_result && r) = default;
41
42 constexpr /*explicit*/ checked_result(const R & r) noexcept :
43 m_e(safe_numerics_error::success),
44 m_contents{r}
45 {}
46
47 constexpr /*explicit*/ checked_result(
48 const safe_numerics_error & e,
49 const char * msg = ""
50 ) noexcept :
51 m_e(e),
52 m_contents{msg}
53 {
54 assert(m_e != safe_numerics_error::success);
55 }
56
57 // permit construct from another checked result type
58 template<typename T>
59 constexpr /*explicit*/ checked_result(const checked_result<T> & t) noexcept :
60 m_e(t.m_e)
61 {
62 static_assert(
63 std::is_convertible<T, R>::value,
64 "T must be convertible to R"
65 );
66 if(safe_numerics_error::success == t.m_e)
67 m_contents.m_r = t.m_r;
68 else
69 m_contents.m_msg = t.m_msg;
70 }
71
72 constexpr bool exception() const {
73 return m_e != safe_numerics_error::success;
74 }
75
76 // accesors
77 constexpr operator R() const noexcept{
78 // don't assert here. Let the library catch these errors
79 // assert(! exception());
80 return m_contents.m_r;
81 }
82
83 constexpr operator safe_numerics_error () const noexcept{
84 // note that this is a legitimate operation even when
85 // the operation was successful - it will return success
86 return m_e;
87 }
88 constexpr operator const char *() const noexcept{
89 assert(exception());
90 return m_contents.m_msg;
91 }
92
93 // disallow assignment
94 checked_result & operator=(const checked_result &) = delete;
95}; // checked_result
96
97template <class R>
98class make_checked_result {
99public:
100 template<safe_numerics_error E>
101 constexpr static checked_result<R> invoke(
102 char const * const & m
103 ) noexcept {
104 return checked_result<R>(E, m);
105 }
106};
107
108} // safe_numerics
109} // boost
110
111#endif // BOOST_NUMERIC_CHECKED_RESULT
112

source code of boost/libs/safe_numerics/include/boost/safe_numerics/checked_result.hpp