]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/type_index/examples/exact_types_match.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / type_index / examples / exact_types_match.cpp
1 // Copyright 2013-2019 Antony Polukhin
2
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See the accompanying file LICENSE_1_0.txt
5 // or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
6
7 //[type_index_exact_type_match_example
8 /*`
9 The following example shows that `type_index` (and `type_info`) is able to store the exact type,
10 without stripping const, volatile and references. Example works with and without RTTI.
11
12 In this example we'll create a class that stores a pointer to function and remembers the exact type of the
13 parameter the function accepts. When the call to the bound function is made, he actual input parameter
14 type is checked against the stored parameter type and an exception is thrown in case of mismatch.
15 */
16
17 #include <boost/type_index.hpp>
18 #include <iostream>
19 #include <stdexcept>
20 #include <cstdlib>
21
22 //<-
23 // Making `#include <cassert>` visible in docs, while actually using hand-made check
24 // instead of `assert`. This is required to verify correct behavior even if NDEBUG
25 // is defined and to avoid `unused local variable` warnings with defined NDEBUG.
26 #ifdef assert
27 # undef assert
28 #endif
29 #define assert(X) if (!(X)) std::exit(__LINE__)
30 /* !Comment block is not closed intentionaly!
31 //->
32 #include <cassert>
33 //<-
34 !Closing comment block! */
35 //->
36
37 class type_erased_unary_function {
38 void* function_ptr_;
39 boost::typeindex::type_index exact_param_t_;
40
41 public:
42 template <class ParamT>
43 type_erased_unary_function(void(*ptr)(ParamT))
44 : function_ptr_(reinterpret_cast<void*>(ptr)) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
45 , exact_param_t_(boost::typeindex::type_id_with_cvr<ParamT>())
46 {}
47
48 template <class ParamT>
49 void call(ParamT v) {
50 if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
51 throw std::runtime_error("Incorrect `ParamT`");
52 }
53
54 return (reinterpret_cast<void(*)(ParamT)>(function_ptr_))(v);
55 }
56 };
57
58 void foo(int){}
59
60 int main() {
61 type_erased_unary_function func(&foo);
62 func.call(100); // OK, `100` has type `int`
63
64 try {
65 int i = 100;
66
67 // An attempt to convert stored function to a function accepting reference
68 func.call<int&>(i); // Will throw, because types `int&` and `int` mismatch
69
70 assert(false);
71 } catch (const std::runtime_error& /*e*/) {}
72 }
73
74 //] [/type_index_exact_type_match_example]