]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/poly_collection/detail/base_model.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / poly_collection / detail / base_model.hpp
CommitLineData
92f5a8d4 1/* Copyright 2016-2018 Joaquin M Lopez Munoz.
b32b8144
FG
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_BASE_MODEL_HPP
10#define BOOST_POLY_COLLECTION_DETAIL_BASE_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/is_final.hpp>
18#include <boost/poly_collection/detail/packed_segment.hpp>
19#include <boost/poly_collection/detail/stride_iterator.hpp>
20#include <memory>
21#include <type_traits>
22#include <typeinfo>
23#include <utility>
24
25namespace boost{
26
27namespace poly_collection{
28
29namespace detail{
30
31/* model for base_collection */
32
33template<typename Base>
34struct base_model
35{
36 using value_type=Base;
37 template<typename Derived>
38 using is_implementation=std::is_base_of<Base,Derived>;
39 template<typename T>
40 using is_terminal=is_final<T>; //TODO: should we say !is_polymorhpic||is_final?
41
42private:
43 template<typename T>
44 using enable_if_not_terminal=
45 typename std::enable_if<!is_terminal<T>::value>::type*;
46 template<typename T>
47 using enable_if_terminal=
48 typename std::enable_if<is_terminal<T>::value>::type*;
49
50public:
51 template<typename T,enable_if_not_terminal<T> =nullptr>
52 static const std::type_info& subtypeid(const T& x){return typeid(x);}
53
54 template<typename T,enable_if_terminal<T> =nullptr>
55 static const std::type_info& subtypeid(const T&){return typeid(T);}
56
57 template<typename T,enable_if_not_terminal<T> =nullptr>
58 static void* subaddress(T& x)
59 {
60 return dynamic_cast<void*>(boost::addressof(x));
61 }
62
63 template<typename T,enable_if_not_terminal<T> =nullptr>
64 static const void* subaddress(const T& x)
65 {
66 return dynamic_cast<const void*>(boost::addressof(x));
67 }
68
69 template<typename T,enable_if_terminal<T> =nullptr>
70 static void* subaddress(T& x){return boost::addressof(x);}
71
72 template<typename T,enable_if_terminal<T> =nullptr>
73 static const void* subaddress(const T& x){return boost::addressof(x);}
74
75 using base_iterator=stride_iterator<Base>;
76 using const_base_iterator=stride_iterator<const Base>;
77 using base_sentinel=Base*;
78 using const_base_sentinel=const Base*;
79 template<typename Derived>
80 using iterator=Derived*;
81 template<typename Derived>
82 using const_iterator=const Derived*;
92f5a8d4
TL
83 template<typename Allocator>
84 using segment_backend=detail::segment_backend<base_model,Allocator>;
b32b8144 85 template<typename Derived,typename Allocator>
92f5a8d4
TL
86 using segment_backend_implementation=
87 packed_segment<base_model,Derived,Allocator>;
b32b8144
FG
88
89 static base_iterator nonconst_iterator(const_base_iterator it)
90 {
91 return {
92 const_cast<value_type*>(static_cast<const value_type*>(it)),
93 it.stride()
94 };
95 }
96
97 template<typename T>
98 static iterator<T> nonconst_iterator(const_iterator<T> it)
99 {
100 return const_cast<iterator<T>>(it);
101 }
102
b32b8144
FG
103private:
104 template<typename,typename,typename>
105 friend class packed_segment;
106
107 template<typename Derived>
108 static const Base* value_ptr(const Derived* p)noexcept
109 {
110 return p;
111 }
112};
113
114} /* namespace poly_collection::detail */
115
116} /* namespace poly_collection */
117
118} /* namespace boost */
119
120#endif