1/* Copyright 2016-2018 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/poly_collection for library home page.
7 */
8
9#ifndef BOOST_POLY_COLLECTION_DETAIL_FUNCTION_MODEL_HPP
10#define BOOST_POLY_COLLECTION_DETAIL_FUNCTION_MODEL_HPP
11
12#if defined(_MSC_VER)
13#pragma once
14#endif
15
16#include <boost/core/addressof.hpp>
17#include <boost/poly_collection/detail/callable_wrapper.hpp>
18#include <boost/poly_collection/detail/callable_wrapper_iterator.hpp>
19#include <boost/poly_collection/detail/is_invocable.hpp>
20#include <boost/poly_collection/detail/segment_backend.hpp>
21#include <boost/poly_collection/detail/split_segment.hpp>
22#include <memory>
23#include <type_traits>
24#include <typeinfo>
25#include <utility>
26
27namespace boost{
28
29namespace poly_collection{
30
31namespace detail{
32
33/* model for function_collection */
34
35template<typename Signature>
36struct function_model;
37
38/* is_terminal defined out-class to allow for partial specialization */
39
40template<typename T>
41struct function_model_is_terminal:std::true_type{};
42
43template<typename Signature>
44struct function_model_is_terminal<callable_wrapper<Signature>>:
45 std::false_type{};
46
47template<typename R,typename... Args>
48struct function_model<R(Args...)>
49{
50 using value_type=callable_wrapper<R(Args...)>;
51
52 template<typename Callable>
53 using is_implementation=is_invocable_r<R,Callable&,Args...>;
54
55 template<typename T>
56 using is_terminal=function_model_is_terminal<T>;
57
58 template<typename T>
59 static const std::type_info& subtypeid(const T&){return typeid(T);}
60
61 template<typename Signature>
62 static const std::type_info& subtypeid(
63 const callable_wrapper<Signature>& f)
64 {
65 return f.target_type();
66 }
67
68 template<typename T>
69 static void* subaddress(T& x){return boost::addressof(x);}
70
71 template<typename T>
72 static const void* subaddress(const T& x){return boost::addressof(x);}
73
74 template<typename Signature>
75 static void* subaddress(callable_wrapper<Signature>& f)
76 {
77 return f.data();
78 }
79
80 template<typename Signature>
81 static const void* subaddress(const callable_wrapper<Signature>& f)
82 {
83 return f.data();
84 }
85
86 using base_iterator=callable_wrapper_iterator<value_type>;
87 using const_base_iterator=callable_wrapper_iterator<const value_type>;
88 using base_sentinel=value_type*;
89 using const_base_sentinel=const value_type*;
90 template<typename Callable>
91 using iterator=Callable*;
92 template<typename Callable>
93 using const_iterator=const Callable*;
94 template<typename Allocator>
95 using segment_backend=detail::segment_backend<function_model,Allocator>;
96 template<typename Callable,typename Allocator>
97 using segment_backend_implementation=
98 split_segment<function_model,Callable,Allocator>;
99
100 static base_iterator nonconst_iterator(const_base_iterator it)
101 {
102 return base_iterator{
103 const_cast<value_type*>(static_cast<const value_type*>(it))};
104 }
105
106 template<typename T>
107 static iterator<T> nonconst_iterator(const_iterator<T> it)
108 {
109 return const_cast<iterator<T>>(it);
110 }
111
112private:
113 template<typename,typename,typename>
114 friend class split_segment;
115
116 template<typename Callable>
117 static value_type make_value_type(Callable& x){return value_type{x};}
118};
119
120} /* namespace poly_collection::detail */
121
122} /* namespace poly_collection */
123
124} /* namespace boost */
125
126#endif
127

source code of boost/libs/poly_collection/include/boost/poly_collection/detail/function_model.hpp