1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // Copyright 2013-2019 Antony Polukhin
- // Distributed under the Boost Software License, Version 1.0.
- // (See the accompanying file LICENSE_1_0.txt
- // or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
- //[type_index_exact_type_match_example
- /*`
- The following example shows that `type_index` (and `type_info`) is able to store the exact type,
- without stripping const, volatile and references. Example works with and without RTTI.
- In this example we'll create a class that stores a pointer to function and remembers the exact type of the
- parameter the function accepts. When the call to the bound function is made, he actual input parameter
- type is checked against the stored parameter type and an exception is thrown in case of mismatch.
- */
- #include <boost/type_index.hpp>
- #include <iostream>
- #include <stdexcept>
- #include <cstdlib>
-
- //<-
- // Making `#include <cassert>` visible in docs, while actually using hand-made check
- // instead of `assert`. This is required to verify correct behavior even if NDEBUG
- // is defined and to avoid `unused local variable` warnings with defined NDEBUG.
- #ifdef assert
- # undef assert
- #endif
- #define assert(X) if (!(X)) std::exit(__LINE__)
- /* !Comment block is not closed intentionaly!
- //->
- #include <cassert>
- //<-
- !Closing comment block! */
- //->
- class type_erased_unary_function {
- void* function_ptr_;
- boost::typeindex::type_index exact_param_t_;
- public:
- template <class ParamT>
- type_erased_unary_function(void(*ptr)(ParamT))
- : function_ptr_(reinterpret_cast<void*>(ptr)) // ptr - is a pointer to function returning `void` and accepting parameter of type `ParamT`
- , exact_param_t_(boost::typeindex::type_id_with_cvr<ParamT>())
- {}
- template <class ParamT>
- void call(ParamT v) {
- if (exact_param_t_ != boost::typeindex::type_id_with_cvr<ParamT>()) {
- throw std::runtime_error("Incorrect `ParamT`");
- }
- return (reinterpret_cast<void(*)(ParamT)>(function_ptr_))(v);
- }
- };
- void foo(int){}
- int main() {
- type_erased_unary_function func(&foo);
- func.call(100); // OK, `100` has type `int`
- try {
- int i = 100;
-
- // An attempt to convert stored function to a function accepting reference
- func.call<int&>(i); // Will throw, because types `int&` and `int` mismatch
- assert(false);
- } catch (const std::runtime_error& /*e*/) {}
- }
- //] [/type_index_exact_type_match_example]
|