Chris@101
|
1 /* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
Chris@16
|
2 * Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 * (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 * http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5 *
|
Chris@16
|
6 * See http://www.boost.org/libs/multi_index for library home page.
|
Chris@16
|
7 */
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
|
Chris@16
|
10 #define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP
|
Chris@16
|
11
|
Chris@101
|
12 #if defined(_MSC_VER)
|
Chris@16
|
13 #pragma once
|
Chris@16
|
14 #endif
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
Chris@16
|
17 #include <algorithm>
|
Chris@16
|
18 #include <boost/detail/allocator_utilities.hpp>
|
Chris@16
|
19 #include <boost/multi_index/detail/adl_swap.hpp>
|
Chris@16
|
20 #include <boost/noncopyable.hpp>
|
Chris@16
|
21 #include <memory>
|
Chris@16
|
22
|
Chris@16
|
23 namespace boost{
|
Chris@16
|
24
|
Chris@16
|
25 namespace multi_index{
|
Chris@16
|
26
|
Chris@16
|
27 namespace detail{
|
Chris@16
|
28
|
Chris@16
|
29 /* auto_space provides uninitialized space suitably to store
|
Chris@16
|
30 * a given number of elements of a given type.
|
Chris@16
|
31 */
|
Chris@16
|
32
|
Chris@16
|
33 /* NB: it is not clear whether using an allocator to handle
|
Chris@16
|
34 * zero-sized arrays of elements is conformant or not. GCC 3.3.1
|
Chris@16
|
35 * and prior fail here, other stdlibs handle the issue gracefully.
|
Chris@16
|
36 * To be on the safe side, the case n==0 is given special treatment.
|
Chris@16
|
37 * References:
|
Chris@16
|
38 * GCC Bugzilla, "standard allocator crashes when deallocating segment
|
Chris@16
|
39 * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176
|
Chris@16
|
40 * C++ Standard Library Defect Report List (Revision 28), issue 199
|
Chris@16
|
41 * "What does allocate(0) return?",
|
Chris@101
|
42 * http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199
|
Chris@16
|
43 */
|
Chris@16
|
44
|
Chris@16
|
45 template<typename T,typename Allocator=std::allocator<T> >
|
Chris@16
|
46 struct auto_space:private noncopyable
|
Chris@16
|
47 {
|
Chris@101
|
48 typedef typename boost::detail::allocator::rebind_to<
|
Chris@101
|
49 Allocator,T
|
Chris@16
|
50 >::type::pointer pointer;
|
Chris@16
|
51
|
Chris@16
|
52 explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1):
|
Chris@16
|
53 al_(al),n_(n),data_(n_?al_.allocate(n_):pointer(0))
|
Chris@16
|
54 {}
|
Chris@16
|
55
|
Chris@16
|
56 ~auto_space()
|
Chris@16
|
57 {
|
Chris@16
|
58 if(n_)al_.deallocate(data_,n_);
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 Allocator get_allocator()const{return al_;}
|
Chris@16
|
62
|
Chris@16
|
63 pointer data()const{return data_;}
|
Chris@16
|
64
|
Chris@16
|
65 void swap(auto_space& x)
|
Chris@16
|
66 {
|
Chris@16
|
67 if(al_!=x.al_)adl_swap(al_,x.al_);
|
Chris@16
|
68 std::swap(n_,x.n_);
|
Chris@16
|
69 std::swap(data_,x.data_);
|
Chris@16
|
70 }
|
Chris@16
|
71
|
Chris@16
|
72 private:
|
Chris@16
|
73 typename boost::detail::allocator::rebind_to<
|
Chris@16
|
74 Allocator,T>::type al_;
|
Chris@16
|
75 std::size_t n_;
|
Chris@16
|
76 pointer data_;
|
Chris@16
|
77 };
|
Chris@16
|
78
|
Chris@16
|
79 template<typename T,typename Allocator>
|
Chris@16
|
80 void swap(auto_space<T,Allocator>& x,auto_space<T,Allocator>& y)
|
Chris@16
|
81 {
|
Chris@16
|
82 x.swap(y);
|
Chris@16
|
83 }
|
Chris@16
|
84
|
Chris@16
|
85 } /* namespace multi_index::detail */
|
Chris@16
|
86
|
Chris@16
|
87 } /* namespace multi_index */
|
Chris@16
|
88
|
Chris@16
|
89 } /* namespace boost */
|
Chris@16
|
90
|
Chris@16
|
91 #endif
|