]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright 2019 Hans Dembinski |
2 | // | |
3 | // Distributed under the Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt | |
5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | #ifndef BOOST_HISTOGRAM_DETAIL_TRY_CAST_HPP | |
8 | #define BOOST_HISTOGRAM_DETAIL_TRY_CAST_HPP | |
9 | ||
20effc67 | 10 | #include <boost/config.hpp> // BOOST_NORETURN |
92f5a8d4 | 11 | #include <boost/throw_exception.hpp> |
92f5a8d4 TL |
12 | #include <type_traits> |
13 | ||
14 | namespace boost { | |
15 | namespace histogram { | |
16 | namespace detail { | |
20effc67 TL |
17 | |
18 | template <class T, class U> | |
19 | constexpr T* ptr_cast(U*) noexcept { | |
20 | return nullptr; | |
21 | } | |
22 | ||
23 | template <class T> | |
24 | constexpr T* ptr_cast(T* p) noexcept { | |
25 | return p; | |
26 | } | |
27 | ||
28 | template <class T> | |
29 | constexpr const T* ptr_cast(const T* p) noexcept { | |
30 | return p; | |
92f5a8d4 TL |
31 | } |
32 | ||
33 | template <class T, class E, class U> | |
20effc67 TL |
34 | BOOST_NORETURN T try_cast_impl(std::false_type, std::false_type, U&&) { |
35 | BOOST_THROW_EXCEPTION(E("type cast error")); | |
92f5a8d4 TL |
36 | } |
37 | ||
20effc67 | 38 | // converting cast |
92f5a8d4 | 39 | template <class T, class E, class U> |
20effc67 TL |
40 | T try_cast_impl(std::false_type, std::true_type, U&& u) noexcept { |
41 | return static_cast<T>(u); // cast to avoid warnings | |
42 | } | |
43 | ||
44 | // pass-through cast | |
45 | template <class T, class E> | |
46 | T&& try_cast_impl(std::true_type, std::true_type, T&& t) noexcept { | |
47 | return std::forward<T>(t); | |
92f5a8d4 TL |
48 | } |
49 | ||
50 | // cast fails at runtime with exception E instead of compile-time, T must be a value | |
51 | template <class T, class E, class U> | |
20effc67 TL |
52 | T try_cast(U&& u) noexcept(std::is_convertible<U, T>::value) { |
53 | return try_cast_impl<T, E>(std::is_same<U, T>{}, std::is_convertible<U, T>{}, | |
92f5a8d4 TL |
54 | std::forward<U>(u)); |
55 | } | |
56 | ||
57 | } // namespace detail | |
58 | } // namespace histogram | |
59 | } // namespace boost | |
60 | ||
61 | #endif |