Skip to content

Commit 07a6a42

Browse files
committed
Differentiate between precondition checks and internal assertions
1 parent f91299e commit 07a6a42

15 files changed

+64
-36
lines changed

CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,26 @@ project(TYPE_SAFE)
88
include(external/external.cmake)
99

1010
# options
11-
option(TYPE_SAFE_ENABLE_ASSERTIONS "whether or not to enable assertions for the type_safe library" ON)
11+
if(CMAKE_BUILD_TYPE MATCHES Debug)
12+
set(_type_safe_default_assertions ON)
13+
else()
14+
set(_type_safe_default_assertions OFF)
15+
endif()
16+
17+
option(TYPE_SAFE_ENABLE_ASSERTIONS "whether or not to enable internal assertions for the type_safe library" ${_type_safe_default_assertions})
1218
if(${TYPE_SAFE_ENABLE_ASSERTIONS})
1319
set(_type_safe_enable_assertions 1)
1420
else()
1521
set(_type_safe_enable_assertions 0)
1622
endif()
1723

24+
option(TYPE_SAFE_ENABLE_PRECONDITION_CHECKS "whether or not to enable precondition checks" ON)
25+
if(${TYPE_SAFE_ENABLE_PRECONDITION_CHECKS})
26+
set(_type_safe_enable_precondition_checks 1)
27+
else()
28+
set(_type_safe_enable_precondition_checks 0)
29+
endif()
30+
1831
option(TYPE_SAFE_ENABLE_WRAPPER "whether or not the wrappers in types.hpp are used" ON)
1932
if(${TYPE_SAFE_ENABLE_WRAPPER})
2033
set(_type_safe_enable_wrapper 1)
@@ -66,6 +79,7 @@ target_sources(type_safe INTERFACE ${detail_header_files} ${header_files})
6679
target_include_directories(type_safe INTERFACE include/)
6780
target_compile_definitions(type_safe INTERFACE
6881
TYPE_SAFE_ENABLE_ASSERTIONS=${_type_safe_enable_assertions}
82+
TYPE_SAFE_ENABLE_PRECONDITION_CHECKS=${_type_safe_enable_precondition_checks}
6983
TYPE_SAFE_ENABLE_WRAPPER=${_type_safe_enable_wrapper}
7084
TYPE_SAFE_ARITHMETIC_UB=${_type_safe_arithmetic_ub})
7185
target_link_libraries(type_safe INTERFACE debug_assert)

include/type_safe/arithmetic_policy.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ namespace type_safe
138138
TYPE_SAFE_FORCE_INLINE static constexpr T do_addition(const T& a, const T& b) noexcept
139139
{
140140
return detail::will_addition_error(detail::arithmetic_tag_for<T>{}, a, b) ?
141-
(DEBUG_UNREACHABLE(detail::assert_handler{},
141+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{},
142142
"addition will result in overflow"),
143143
a) :
144144
a + b;
@@ -148,7 +148,7 @@ namespace type_safe
148148
TYPE_SAFE_FORCE_INLINE static constexpr T do_subtraction(const T& a, const T& b) noexcept
149149
{
150150
return detail::will_subtraction_error(detail::arithmetic_tag_for<T>{}, a, b) ?
151-
(DEBUG_UNREACHABLE(detail::assert_handler{},
151+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{},
152152
"subtraction will result in underflow"),
153153
a) :
154154
a - b;
@@ -158,7 +158,7 @@ namespace type_safe
158158
TYPE_SAFE_FORCE_INLINE static constexpr T do_multiplication(const T& a, const T& b) noexcept
159159
{
160160
return detail::will_multiplication_error(detail::arithmetic_tag_for<T>{}, a, b) ?
161-
(DEBUG_UNREACHABLE(detail::assert_handler{},
161+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{},
162162
"multiplication will result in overflow"),
163163
a) :
164164
a * b;
@@ -168,7 +168,8 @@ namespace type_safe
168168
TYPE_SAFE_FORCE_INLINE static constexpr T do_division(const T& a, const T& b) noexcept
169169
{
170170
return detail::will_division_error(detail::arithmetic_tag_for<T>{}, a, b) ?
171-
(DEBUG_UNREACHABLE(detail::assert_handler{}, "division by zero/overflow"),
171+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{},
172+
"division by zero/overflow"),
172173
a) :
173174
a / b;
174175
}
@@ -177,7 +178,8 @@ namespace type_safe
177178
TYPE_SAFE_FORCE_INLINE static constexpr T do_modulo(const T& a, const T& b) noexcept
178179
{
179180
return detail::will_modulo_error(detail::arithmetic_tag_for<T>{}, a, b) ?
180-
(DEBUG_UNREACHABLE(detail::assert_handler{}, "modulo by zero"), a) :
181+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{}, "modulo by zero"),
182+
a) :
181183
a % b;
182184
}
183185
};
@@ -195,7 +197,7 @@ namespace type_safe
195197
error(const char* msg) : std::range_error(msg)
196198
{
197199
#if !TYPE_SAFE_USE_EXCEPTIONS
198-
DEBUG_UNREACHABLE(detail::assert_handler{}, msg);
200+
DEBUG_UNREACHABLE(detail::precondition_error_handler{}, msg);
199201
#endif
200202
}
201203
};

include/type_safe/compact_optional.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace type_safe
7878
typename std::enable_if<std::is_constructible<value_type, Args&&...>::value>::type
7979
{
8080
storage_ = static_cast<storage_type>(value_type(std::forward<Args>(args)...));
81-
DEBUG_ASSERT(has_value(), detail::assert_handler{},
81+
DEBUG_ASSERT(has_value(), detail::precondition_error_handler{},
8282
"create_value() called creating an invalid value");
8383
}
8484

include/type_safe/config.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@
99
#include <cstdlib>
1010

1111
#ifndef TYPE_SAFE_ENABLE_ASSERTIONS
12-
#define TYPE_SAFE_ENABLE_ASSERTIONS 1
12+
#define TYPE_SAFE_ENABLE_ASSERTIONS 0
13+
#endif
14+
15+
#ifndef TYPE_SAFE_ENABLE_PRECONDITION_CHECKS
16+
#define TYPE_SAFE_ENABLE_PRECONDITION_CHECKS 1
1317
#endif
1418

1519
#ifndef TYPE_SAFE_ENABLE_WRAPPER

include/type_safe/constrained_type.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ namespace type_safe
2121
template <typename Value, typename Predicate>
2222
static void verify(const Value& val, const Predicate& p)
2323
{
24-
DEBUG_ASSERT(p(val), detail::assert_handler{}, "value does not fulfill constraint");
24+
DEBUG_ASSERT(p(val), detail::precondition_error_handler{},
25+
"value does not fulfill constraint");
2526
}
2627
};
2728

@@ -185,7 +186,7 @@ namespace type_safe
185186
/// \requires It must not be in the moved-from state.
186187
value_type& get() noexcept
187188
{
188-
DEBUG_ASSERT(value_, detail::assert_handler{});
189+
DEBUG_ASSERT(value_, detail::precondition_error_handler{});
189190
return value_->value_;
190191
}
191192

include/type_safe/deferred_construction.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ namespace type_safe
107107
template <typename... Args>
108108
void emplace(Args&&... args)
109109
{
110-
DEBUG_ASSERT(!has_value(), detail::assert_handler{});
110+
DEBUG_ASSERT(!has_value(), detail::precondition_error_handler{});
111111
::new (as_void()) value_type(std::forward<Args>(args)...);
112112
initialized_ = true;
113113
}
@@ -129,15 +129,15 @@ namespace type_safe
129129
/// \requires `has_value() == true`.
130130
value_type& value() TYPE_SAFE_LVALUE_REF noexcept
131131
{
132-
DEBUG_ASSERT(has_value(), detail::assert_handler{});
132+
DEBUG_ASSERT(has_value(), detail::precondition_error_handler{});
133133
return *static_cast<value_type*>(as_void());
134134
}
135135

136136
/// \returns A `const` reference to the stored value.
137137
/// \requires `has_value() == true`.
138138
const value_type& value() const TYPE_SAFE_LVALUE_REF noexcept
139139
{
140-
DEBUG_ASSERT(has_value(), detail::assert_handler{});
140+
DEBUG_ASSERT(has_value(), detail::precondition_error_handler{});
141141
return *static_cast<const value_type*>(as_void());
142142
}
143143

@@ -146,15 +146,15 @@ namespace type_safe
146146
/// \requires `has_value() == true`.
147147
value_type&& value() && noexcept
148148
{
149-
DEBUG_ASSERT(has_value(), detail::assert_handler{});
149+
DEBUG_ASSERT(has_value(), detail::precondition_error_handler{});
150150
return std::move(*static_cast<value_type*>(as_void()));
151151
}
152152

153153
/// \returns An rvalue reference to the stored value.
154154
/// \requires `has_value() == true`.
155155
const value_type&& value() const && noexcept
156156
{
157-
DEBUG_ASSERT(has_value(), detail::assert_handler{});
157+
DEBUG_ASSERT(has_value(), detail::precondition_error_handler{});
158158
return std::move(*static_cast<const value_type*>(as_void()));
159159
}
160160
#endif

include/type_safe/detail/assert.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ namespace type_safe
1717
debug_assert::default_handler
1818
{
1919
};
20+
21+
struct precondition_error_handler
22+
: debug_assert::set_level<TYPE_SAFE_ENABLE_PRECONDITION_CHECKS>,
23+
debug_assert::default_handler
24+
{
25+
};
2026
} // namespace detail
2127
} // namespace type_safe
2228

include/type_safe/flag.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace type_safe
7878
template <typename T, typename = detail::enable_boolean<T>>
7979
void change(T new_state) noexcept
8080
{
81-
DEBUG_ASSERT(state_ != new_state, detail::assert_handler{});
81+
DEBUG_ASSERT(state_ != new_state, detail::precondition_error_handler{});
8282
state_ = new_state;
8383
}
8484

include/type_safe/index.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ namespace type_safe
174174
{
175175
DEBUG_ASSERT(detail::index_valid(detail::member_size{}, obj,
176176
static_cast<std::size_t>(get(index))),
177-
detail::assert_handler{});
177+
detail::precondition_error_handler{});
178178
return std::forward<Indexable>(obj)[static_cast<std::size_t>(get(index))];
179179
}
180180

include/type_safe/integer.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,9 @@ namespace type_safe
352352
using result_type = make_signed_t<Integer>;
353353
return i <= Integer(std::numeric_limits<result_type>::max()) ?
354354
static_cast<result_type>(i) :
355-
(DEBUG_UNREACHABLE(detail::assert_handler{}, "conversion "
356-
"would "
357-
"overflow"),
355+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{}, "conversion "
356+
"would "
357+
"overflow"),
358358
result_type());
359359
}
360360

@@ -383,10 +383,10 @@ namespace type_safe
383383
TYPE_SAFE_FORCE_INLINE constexpr make_unsigned_t<Integer> make_unsigned(const Integer& i)
384384
{
385385
using result_type = make_unsigned_t<Integer>;
386-
return i >= Integer(0) ?
387-
static_cast<result_type>(i) :
388-
(DEBUG_UNREACHABLE(detail::assert_handler{}, "conversion would underflow"),
389-
result_type(0));
386+
return i >= Integer(0) ? static_cast<result_type>(i) :
387+
(DEBUG_UNREACHABLE(detail::precondition_error_handler{},
388+
"conversion would underflow"),
389+
result_type(0));
390390
}
391391

392392
/// \returns A new [ts::integer]() of the corresponding unsigned integer type.

0 commit comments

Comments
 (0)