1 | // Boost.TypeErasure library |
---|---|
2 | // |
3 | // Copyright 2015 Steven Watanabe |
4 | // |
5 | // Distributed under the Boost Software License Version 1.0. (See |
6 | // accompanying file LICENSE_1_0.txt or copy at |
7 | // http://www.boost.org/LICENSE_1_0.txt) |
8 | // |
9 | // $Id$ |
10 | |
11 | #define BOOST_TYPE_ERASURE_SOURCE |
12 | |
13 | #include <boost/type_erasure/register_binding.hpp> |
14 | #include <boost/thread/shared_mutex.hpp> |
15 | #include <boost/thread/lock_types.hpp> |
16 | #include <map> |
17 | #include <utility> |
18 | |
19 | namespace { |
20 | |
21 | using ::boost::type_erasure::detail::key_type; |
22 | using ::boost::type_erasure::detail::value_type; |
23 | |
24 | typedef ::std::map<key_type, void(*)()> map_type; |
25 | typedef ::boost::shared_mutex mutex_type; |
26 | |
27 | // std::pair can have problems on older implementations |
28 | // when it tries to use the copy constructor of the mutex. |
29 | struct data_type |
30 | { |
31 | map_type first; |
32 | mutex_type second; |
33 | }; |
34 | |
35 | data_type * get_data() { |
36 | static data_type result; |
37 | return &result; |
38 | } |
39 | |
40 | } |
41 | |
42 | BOOST_TYPE_ERASURE_DECL void boost::type_erasure::detail::register_function_impl(const key_type& key, value_type fn) { |
43 | ::data_type * data = ::get_data(); |
44 | ::boost::unique_lock<mutex_type> lock(data->second); |
45 | data->first.insert(x: std::make_pair(x: key, y&: fn)); |
46 | } |
47 | |
48 | BOOST_TYPE_ERASURE_DECL value_type boost::type_erasure::detail::lookup_function_impl(const key_type& key) { |
49 | ::data_type * data = ::get_data(); |
50 | ::boost::shared_lock<mutex_type> lock(data->second); |
51 | ::map_type::const_iterator pos = data->first.find(x: key); |
52 | if(pos != data->first.end()) { |
53 | return pos->second; |
54 | } else { |
55 | throw bad_any_cast(); |
56 | } |
57 | } |
58 |