]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/container/detail/allocator_version_traits.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / container / detail / allocator_version_traits.hpp
CommitLineData
7c673cae
FG
1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10
11#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
12#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
13
14#ifndef BOOST_CONFIG_HPP
15# include <boost/config.hpp>
16#endif
17
18#if defined(BOOST_HAS_PRAGMA_ONCE)
19# pragma once
20#endif
21
22#include <boost/container/detail/config_begin.hpp>
23#include <boost/container/detail/workaround.hpp>
24
25#include <boost/container/allocator_traits.hpp> //allocator_traits
26#include <boost/container/throw_exception.hpp>
27#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
28#include <boost/container/detail/version_type.hpp> //version_type
29#include <boost/container/detail/allocation_type.hpp> //allocation_type
30#include <boost/container/detail/mpl.hpp> //integral_constant
31#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
32#include <boost/core/no_exceptions_support.hpp> //BOOST_TRY
33
34namespace boost {
35namespace container {
11fdf7f2 36namespace dtl {
7c673cae 37
11fdf7f2 38template<class Allocator, unsigned Version = boost::container::dtl::version<Allocator>::value>
7c673cae
FG
39struct allocator_version_traits
40{
11fdf7f2 41 typedef ::boost::container::dtl::integral_constant
7c673cae
FG
42 <unsigned, Version> alloc_version;
43
44 typedef typename Allocator::multiallocation_chain multiallocation_chain;
45
46 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
47 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
48
49 //Node allocation interface
50 static pointer allocate_one(Allocator &a)
51 { return a.allocate_one(); }
52
53 static void deallocate_one(Allocator &a, const pointer &p)
54 { a.deallocate_one(p); }
55
56 static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
57 { return a.allocate_individual(n, m); }
58
59 static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
60 { a.deallocate_individual(holder); }
61
62 static pointer allocation_command(Allocator &a, allocation_type command,
63 size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
64 { return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); }
65};
66
67template<class Allocator>
68struct allocator_version_traits<Allocator, 1>
69{
11fdf7f2 70 typedef ::boost::container::dtl::integral_constant
7c673cae
FG
71 <unsigned, 1> alloc_version;
72
73 typedef typename boost::container::allocator_traits<Allocator>::pointer pointer;
74 typedef typename boost::container::allocator_traits<Allocator>::size_type size_type;
75 typedef typename boost::container::allocator_traits<Allocator>::value_type value_type;
76
77 typedef typename boost::intrusive::pointer_traits<pointer>::
78 template rebind_pointer<void>::type void_ptr;
11fdf7f2 79 typedef dtl::basic_multiallocation_chain
7c673cae 80 <void_ptr> multialloc_cached_counted;
11fdf7f2 81 typedef boost::container::dtl::
7c673cae
FG
82 transform_multiallocation_chain
83 < multialloc_cached_counted, value_type> multiallocation_chain;
84
85 //Node allocation interface
86 static pointer allocate_one(Allocator &a)
87 { return a.allocate(1); }
88
89 static void deallocate_one(Allocator &a, const pointer &p)
90 { a.deallocate(p, 1); }
91
92 static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
93 {
94 size_type n = holder.size();
95 typename multiallocation_chain::iterator it = holder.begin();
92f5a8d4
TL
96 while(n){
97 --n;
7c673cae
FG
98 pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
99 ++it;
100 a.deallocate(p, 1);
101 }
102 }
103
104 struct allocate_individual_rollback
105 {
106 allocate_individual_rollback(Allocator &a, multiallocation_chain &chain)
107 : mr_a(a), mp_chain(&chain)
108 {}
109
110 ~allocate_individual_rollback()
111 {
112 if(mp_chain)
113 allocator_version_traits::deallocate_individual(mr_a, *mp_chain);
114 }
115
116 void release()
117 {
118 mp_chain = 0;
119 }
120
121 Allocator &mr_a;
122 multiallocation_chain * mp_chain;
123 };
124
125 static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m)
126 {
127 allocate_individual_rollback rollback(a, m);
128 while(n--){
129 m.push_front(a.allocate(1));
130 }
131 rollback.release();
132 }
133
134 static pointer allocation_command(Allocator &a, allocation_type command,
135 size_type, size_type &prefer_in_recvd_out_size, pointer &reuse)
136 {
137 pointer ret = pointer();
138 if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){
139 throw_logic_error("version 1 allocator without allocate_new flag");
140 }
141 else{
142 BOOST_TRY{
143 ret = a.allocate(prefer_in_recvd_out_size);
144 }
145 BOOST_CATCH(...){
146 if(!(command & nothrow_allocation)){
147 BOOST_RETHROW
148 }
149 }
150 BOOST_CATCH_END
151 reuse = pointer();
152 }
153 return ret;
154 }
155};
156
11fdf7f2 157} //namespace dtl {
7c673cae
FG
158} //namespace container {
159} //namespace boost {
160
161#include <boost/container/detail/config_end.hpp>
162
163#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)