]>
Commit | Line | Data |
---|---|---|
1e59de90 | 1 | /* Copyright 2003-2022 Joaquin M Lopez Munoz. |
7c673cae 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/multi_index for library home page. | |
7 | */ | |
8 | ||
9 | #ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP | |
10 | #define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP | |
11 | ||
12 | #if defined(_MSC_VER) | |
13 | #pragma once | |
14 | #endif | |
15 | ||
16 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ | |
17 | #include <algorithm> | |
1e59de90 | 18 | #include <boost/core/noncopyable.hpp> |
7c673cae | 19 | #include <boost/multi_index/detail/adl_swap.hpp> |
92f5a8d4 | 20 | #include <boost/multi_index/detail/allocator_traits.hpp> |
f67539c2 | 21 | #include <boost/type_traits/integral_constant.hpp> |
7c673cae FG |
22 | #include <memory> |
23 | ||
24 | namespace boost{ | |
25 | ||
26 | namespace multi_index{ | |
27 | ||
28 | namespace detail{ | |
29 | ||
30 | /* auto_space provides uninitialized space suitably to store | |
31 | * a given number of elements of a given type. | |
32 | */ | |
33 | ||
34 | /* NB: it is not clear whether using an allocator to handle | |
35 | * zero-sized arrays of elements is conformant or not. GCC 3.3.1 | |
36 | * and prior fail here, other stdlibs handle the issue gracefully. | |
37 | * To be on the safe side, the case n==0 is given special treatment. | |
38 | * References: | |
39 | * GCC Bugzilla, "standard allocator crashes when deallocating segment | |
40 | * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176 | |
41 | * C++ Standard Library Defect Report List (Revision 28), issue 199 | |
42 | * "What does allocate(0) return?", | |
43 | * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199 | |
44 | */ | |
45 | ||
46 | template<typename T,typename Allocator=std::allocator<T> > | |
47 | struct auto_space:private noncopyable | |
48 | { | |
92f5a8d4 TL |
49 | typedef typename rebind_alloc_for< |
50 | Allocator,T> | |
51 | ::type allocator; | |
52 | typedef allocator_traits<allocator> alloc_traits; | |
53 | typedef typename alloc_traits::pointer pointer; | |
54 | typedef typename alloc_traits::size_type size_type; | |
55 | ||
56 | explicit auto_space(const Allocator& al=Allocator(),size_type n=1): | |
57 | al_(al),n_(n),data_(n_?alloc_traits::allocate(al_,n_):pointer(0)) | |
7c673cae FG |
58 | {} |
59 | ||
92f5a8d4 | 60 | ~auto_space(){if(n_)alloc_traits::deallocate(al_,data_,n_);} |
7c673cae FG |
61 | |
62 | Allocator get_allocator()const{return al_;} | |
63 | ||
64 | pointer data()const{return data_;} | |
65 | ||
66 | void swap(auto_space& x) | |
67 | { | |
f67539c2 TL |
68 | swap( |
69 | x, | |
70 | boost::integral_constant< | |
71 | bool,alloc_traits::propagate_on_container_swap::value>()); | |
72 | } | |
73 | ||
74 | void swap(auto_space& x,boost::true_type /* swap_allocators */) | |
75 | { | |
76 | adl_swap(al_,x.al_); | |
7c673cae FG |
77 | std::swap(n_,x.n_); |
78 | std::swap(data_,x.data_); | |
79 | } | |
80 | ||
f67539c2 TL |
81 | void swap(auto_space& x,boost::false_type /* swap_allocators */) |
82 | { | |
83 | std::swap(n_,x.n_); | |
84 | std::swap(data_,x.data_); | |
85 | } | |
86 | ||
7c673cae | 87 | private: |
92f5a8d4 TL |
88 | allocator al_; |
89 | size_type n_; | |
90 | pointer data_; | |
7c673cae FG |
91 | }; |
92 | ||
93 | template<typename T,typename Allocator> | |
94 | void swap(auto_space<T,Allocator>& x,auto_space<T,Allocator>& y) | |
95 | { | |
96 | x.swap(y); | |
97 | } | |
98 | ||
99 | } /* namespace multi_index::detail */ | |
100 | ||
101 | } /* namespace multi_index */ | |
102 | ||
103 | } /* namespace boost */ | |
104 | ||
105 | #endif |