MCKL
Monte Carlo Kernel Library
assert.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/internal/assert.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_INTERNAL_ASSERT_HPP
33 #define MCKL_INTERNAL_ASSERT_HPP
34 
35 #include <mckl/internal/config.h>
36 
37 #include <cassert>
38 #include <cmath>
39 #include <exception>
40 #include <iostream>
41 #include <limits>
42 #include <stdexcept>
43 #include <string>
44 
45 MCKL_PUSH_CLANG_WARNING("-Wweak-vtables")
46 
47 namespace mckl {
48 
49 class RuntimeAssert : public std::runtime_error
50 {
51  public:
52  explicit RuntimeAssert(const char *msg) : std::runtime_error(msg) {}
53 
54  explicit RuntimeAssert(const std::string &msg) : std::runtime_error(msg) {}
55 }; // class RuntimeAssert
56 
57 #if MCKL_NO_RUNTIME_ASSERT
58 
59 inline void runtime_assert(bool, const char *, bool = false) {}
60 
61 inline void runtime_assert(bool, const std::string &, bool = false) {}
62 
63 #else // MCKL_NO_RUNTIME_ASSERT
64 
65 inline void runtime_assert(bool cond, const char *msg, bool soft = false)
66 {
67 #if MCKL_RUNTIME_ASSERT_AS_EXCEPTION
68  if (!cond)
69  throw ::mckl::RuntimeAssert(msg);
70 #else // MCKL_RUNTIME_ASSERT_AS_EXCEPTION
71  if (!cond)
72  std::cerr << "MCKL runtime assertion failed: " << msg << std::endl;
73  if (!soft)
74  assert(cond);
75 #endif // MCKL_RUNTIME_ASSERT_AS_EXCEPTION
76 }
77 
78 inline void runtime_assert(
79  bool cond, const std::string &msg, bool soft = false)
80 {
81  runtime_assert(cond, msg.c_str(), soft);
82 }
83 
84 #endif // MCKL_NO_RUNTIME_ASSERT
85 
86 template <typename Except>
87 inline void runtime_assert(bool cond, const char *msg)
88 {
89  if (!cond) {
90  throw Except(msg);
91  }
92 }
93 
94 template <typename Except>
95 inline void runtime_assert(bool cond, const std::string &msg)
96 {
97  runtime_assert<Except>(cond, msg.c_str());
98 }
99 
100 namespace internal {
101 
102 #if MCKL_NO_RUNTIME_ASSERT
103 
104 template <typename IntType, typename SizeType>
105 inline void size_check(SizeType, const char *)
106 {
107 }
108 
109 #else // MCKL_NO_RUNTIME_ASSERT
110 
111 template <typename IntType, typename SizeType>
112 inline void size_check(SizeType, const char *, std::false_type)
113 {
114 }
115 
116 template <typename IntType, typename SizeType>
117 inline void size_check(SizeType n, const char *f, std::true_type)
118 {
119  constexpr std::uintmax_t nmax =
120  static_cast<std::uintmax_t>(std::numeric_limits<IntType>::max());
121 
122  std::string msg;
123  msg += "**";
124  msg += f;
125  msg += "** input size too large";
126 
127  runtime_assert((static_cast<std::uintmax_t>(n) <= nmax), msg.c_str());
128 }
129 
130 template <typename IntType, typename SizeType>
131 inline void size_check(SizeType n, const char *f)
132 {
133  constexpr std::uintmax_t nmax =
134  static_cast<std::uintmax_t>(std::numeric_limits<IntType>::max());
135  constexpr std::uintmax_t smax =
136  static_cast<std::uintmax_t>(std::numeric_limits<SizeType>::max());
137 
138  size_check<IntType>(n, f, std::integral_constant<bool, (nmax < smax)>());
139 }
140 
141 #endif // MCKL_NO_RUNTIME_ASSERT
142 
143 template <typename T>
144 inline bool is_nullptr(T ptr, std::true_type)
145 {
146  return ptr == nullptr;
147 }
148 
149 template <typename T>
150 inline bool is_nullptr(T, std::false_type)
151 {
152  return false;
153 }
154 
155 template <typename T>
156 inline bool is_nullptr(T ptr)
157 {
158  return is_nullptr(ptr,
159  std::integral_constant<bool,
160  (std::is_pointer<T>::value ||
161  std::is_same<std::nullptr_t, std::remove_cv_t<T>>::value)>());
162 }
163 
164 inline bool is_nullptr(std::nullptr_t) { return true; }
165 
166 } // namespace internal
167 
168 } // namespace mckl
169 
171 
172 #endif // MCKL_INTERNAL_ASSERT_HPP
RuntimeAssert(const std::string &msg)
Definition: assert.hpp:54
RuntimeAssert(const char *msg)
Definition: assert.hpp:52
#define MCKL_PUSH_CLANG_WARNING(warning)
Definition: compiler.h:63
STL namespace.
void runtime_assert(bool cond, const std::string &msg)
Definition: assert.hpp:95
bool is_nullptr(std::nullptr_t)
Definition: assert.hpp:164
Definition: mcmc.hpp:40
#define MCKL_POP_CLANG_WARNING
Definition: compiler.h:66
void size_check(SizeType n, const char *f)
Definition: assert.hpp:131
typename SizeTypeTrait< T >::type SizeType
Definition: traits.hpp:166