williamr@2: /* Copyright 2003-2005 Joaquín M López Muñoz. williamr@2: * Distributed under the Boost Software License, Version 1.0. williamr@2: * (See accompanying file LICENSE_1_0.txt or copy at williamr@2: * http://www.boost.org/LICENSE_1_0.txt) williamr@2: * williamr@2: * See http://www.boost.org/libs/multi_index for library home page. williamr@2: */ williamr@2: williamr@2: #ifndef BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP williamr@2: #define BOOST_MULTI_INDEX_DETAIL_AUTO_SPACE_HPP williamr@2: williamr@2: #if defined(_MSC_VER)&&(_MSC_VER>=1200) williamr@2: #pragma once williamr@2: #endif williamr@2: williamr@2: #include /* keep it first to prevent nasty warns in MSVC */ williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: namespace boost{ williamr@2: williamr@2: namespace multi_index{ williamr@2: williamr@2: namespace detail{ williamr@2: williamr@2: /* auto_space provides uninitialized space suitably to store williamr@2: * a given number of elements of a given type. williamr@2: */ williamr@2: williamr@2: /* NB: it is not clear whether using an allocator to handle williamr@2: * zero-sized arrays of elements is conformant or not. GCC 3.3.1 williamr@2: * and prior fail here, other stdlibs handle the issue gracefully. williamr@2: * To be on the safe side, the case n==0 is given special treatment. williamr@2: * References: williamr@2: * GCC Bugzilla, "standard allocator crashes when deallocating segment williamr@2: * "of zero length", http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14176 williamr@2: * C++ Standard Library Defect Report List (Revision 28), issue 199 williamr@2: * "What does allocate(0) return?", williamr@2: * http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#199 williamr@2: */ williamr@2: williamr@2: template > williamr@2: struct auto_space:private noncopyable williamr@2: { williamr@2: explicit auto_space(const Allocator& al=Allocator(),std::size_t n=1): williamr@2: al_(al),n_(n),data_(n_?al_.allocate(n_):0) williamr@2: {} williamr@2: williamr@2: ~auto_space() williamr@2: { williamr@2: if(n_)al_.deallocate(data_,n_); williamr@2: } williamr@2: williamr@2: Allocator get_allocator()const{return al_;} williamr@2: williamr@2: T* data()const{return data_;} williamr@2: williamr@2: void swap(auto_space& x) williamr@2: { williamr@2: std::swap(n_,x.n_); williamr@2: std::swap(data_,x.data_); williamr@2: } williamr@2: williamr@2: private: williamr@2: typename boost::detail::allocator::rebind_to< williamr@2: Allocator,T>::type al_; williamr@2: std::size_t n_; williamr@2: T* data_; williamr@2: }; williamr@2: williamr@2: template williamr@2: void swap(auto_space& x,auto_space& y) williamr@2: { williamr@2: x.swap(y); williamr@2: } williamr@2: williamr@2: } /* namespace multi_index::detail */ williamr@2: williamr@2: } /* namespace multi_index */ williamr@2: williamr@2: } /* namespace boost */ williamr@2: williamr@2: #endif