Line data Source code
1 : /* Copyright 2003-2022 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/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> 18 : #include <boost/core/noncopyable.hpp> 19 : #include <boost/multi_index/detail/adl_swap.hpp> 20 : #include <boost/multi_index/detail/allocator_traits.hpp> 21 : #include <boost/type_traits/integral_constant.hpp> 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 : { 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 96270 : explicit auto_space(const Allocator& al=Allocator(),size_type n=1): 57 48135 : al_(al),n_(n),data_(n_?alloc_traits::allocate(al_,n_):pointer(0)) 58 96270 : {} 59 : 60 96270 : ~auto_space(){if(n_)alloc_traits::deallocate(al_,data_,n_);} 61 : 62 : Allocator get_allocator()const{return al_;} 63 : 64 2167995 : pointer data()const{return data_;} 65 : 66 15 : void swap(auto_space& x) 67 : { 68 15 : swap( 69 15 : x, 70 : boost::integral_constant< 71 : bool,alloc_traits::propagate_on_container_swap::value>()); 72 15 : } 73 : 74 : void swap(auto_space& x,boost::true_type /* swap_allocators */) 75 : { 76 : adl_swap(al_,x.al_); 77 : std::swap(n_,x.n_); 78 : std::swap(data_,x.data_); 79 : } 80 : 81 15 : void swap(auto_space& x,boost::false_type /* swap_allocators */) 82 : { 83 15 : std::swap(n_,x.n_); 84 15 : std::swap(data_,x.data_); 85 15 : } 86 : 87 : private: 88 : allocator al_; 89 : size_type n_; 90 : pointer data_; 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