forked from boostorg/unordered
		
	
		
			
				
	
	
		
			219 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//  (C) Copyright Daniel James 2005.
 | 
						|
//  Use, modification and distribution are subject to the
 | 
						|
//  Boost Software License, Version 1.0. (See accompanying file
 | 
						|
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 | 
						|
#ifndef BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
 | 
						|
#define BOOST_UNORDERED_DETAIL_ALLOCATOR_UTILITIES_HPP_INCLUDED
 | 
						|
 | 
						|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
						|
# pragma once
 | 
						|
#endif
 | 
						|
 | 
						|
#include <boost/config.hpp>
 | 
						|
 | 
						|
#if (defined(BOOST_NO_STD_ALLOCATOR) || defined(BOOST_DINKUMWARE_STDLIB)) \
 | 
						|
    && !defined(__BORLANDC__)
 | 
						|
#  define BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
 | 
						|
#endif
 | 
						|
 | 
						|
#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
 | 
						|
#  include <boost/detail/allocator_utilities.hpp>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <boost/mpl/aux_/config/eti.hpp>
 | 
						|
 | 
						|
namespace boost {
 | 
						|
    namespace unordered_detail {
 | 
						|
 | 
						|
#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
 | 
						|
        template <class Alloc, class T>
 | 
						|
        struct rebind_wrap : ::boost::detail::allocator::rebind_to<Alloc, T> {};
 | 
						|
#else
 | 
						|
        template <class Alloc, class T>
 | 
						|
        struct rebind_wrap
 | 
						|
        {
 | 
						|
            typedef BOOST_DEDUCED_TYPENAME
 | 
						|
                Alloc::BOOST_NESTED_TEMPLATE rebind<T>::other
 | 
						|
                type;
 | 
						|
        };
 | 
						|
#endif
 | 
						|
 | 
						|
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 | 
						|
        template <class T>
 | 
						|
        inline void reset(T& x) { x  = T(); }
 | 
						|
#else
 | 
						|
        template <class T>
 | 
						|
        inline void reset_impl(T& x, ...) { x  = T(); }
 | 
						|
        template <class T>
 | 
						|
        inline void reset_impl(T*& x, int) { x  = 0; }
 | 
						|
        template <class T>
 | 
						|
        inline void reset(T& x) { reset_impl(x); }
 | 
						|
#endif
 | 
						|
 | 
						|
        // Work around for Microsoft's ETI bug.
 | 
						|
        
 | 
						|
        template <class Allocator> struct allocator_value_type
 | 
						|
        {
 | 
						|
            typedef typename Allocator::value_type type;
 | 
						|
        };
 | 
						|
 | 
						|
        template <class Allocator> struct allocator_pointer
 | 
						|
        {
 | 
						|
            typedef typename Allocator::pointer type;
 | 
						|
        };
 | 
						|
        
 | 
						|
        template <class Allocator> struct allocator_const_pointer
 | 
						|
        {
 | 
						|
            typedef typename Allocator::const_pointer type;
 | 
						|
        };
 | 
						|
        
 | 
						|
        template <class Allocator> struct allocator_reference
 | 
						|
        {
 | 
						|
            typedef typename Allocator::reference type;
 | 
						|
        };
 | 
						|
        
 | 
						|
        template <class Allocator> struct allocator_const_reference
 | 
						|
        {
 | 
						|
            typedef typename Allocator::const_reference type;
 | 
						|
        };
 | 
						|
        
 | 
						|
#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
 | 
						|
 | 
						|
        template <>
 | 
						|
        struct allocator_value_type<int>
 | 
						|
        {
 | 
						|
            typedef int type;
 | 
						|
        };
 | 
						|
 | 
						|
        template <>
 | 
						|
        struct allocator_pointer<int>
 | 
						|
        {
 | 
						|
            typedef int type;
 | 
						|
        };
 | 
						|
 | 
						|
        template <>
 | 
						|
        struct allocator_const_pointer<int>
 | 
						|
        {
 | 
						|
            typedef int type;
 | 
						|
        };
 | 
						|
 | 
						|
        template <>
 | 
						|
        struct allocator_reference<int>
 | 
						|
        {
 | 
						|
            typedef int type;
 | 
						|
        };
 | 
						|
 | 
						|
        template <>
 | 
						|
        struct allocator_const_reference<int>
 | 
						|
        {
 | 
						|
            typedef int type;
 | 
						|
        };
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
        template <class Allocator>
 | 
						|
        struct allocator_constructor
 | 
						|
        {
 | 
						|
            typedef typename allocator_pointer<Allocator>::type pointer;
 | 
						|
 | 
						|
            Allocator& alloc_;
 | 
						|
            pointer ptr_;
 | 
						|
            bool constructed_;
 | 
						|
 | 
						|
            allocator_constructor(Allocator& a)
 | 
						|
                : alloc_(a), ptr_(), constructed_(false)
 | 
						|
            {
 | 
						|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 | 
						|
                    unordered_detail::reset(ptr_);
 | 
						|
#endif
 | 
						|
            }
 | 
						|
 | 
						|
            ~allocator_constructor() {
 | 
						|
                if(ptr_) {
 | 
						|
                    if(constructed_) alloc_.destroy(ptr_);
 | 
						|
                    alloc_.deallocate(ptr_, 1);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            template <class V>
 | 
						|
            void construct(V const& v) {
 | 
						|
                BOOST_ASSERT(!ptr_ && !constructed_);
 | 
						|
                ptr_ = alloc_.allocate(1);
 | 
						|
                alloc_.construct(ptr_, v);
 | 
						|
                constructed_  = true;
 | 
						|
            }
 | 
						|
 | 
						|
            // no throw
 | 
						|
            pointer release()
 | 
						|
            {
 | 
						|
                pointer p = ptr_;
 | 
						|
                constructed_ = false;
 | 
						|
                reset(ptr_);
 | 
						|
                return p;
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        template <class Allocator>
 | 
						|
        struct allocator_array_constructor
 | 
						|
        {
 | 
						|
            typedef typename allocator_pointer<Allocator>::type pointer;
 | 
						|
 | 
						|
            Allocator& alloc_;
 | 
						|
            pointer ptr_;
 | 
						|
            pointer constructed_;
 | 
						|
            std::size_t length_;
 | 
						|
 | 
						|
            allocator_array_constructor(Allocator& a)
 | 
						|
                : alloc_(a), ptr_(), constructed_(), length_(0)
 | 
						|
            {
 | 
						|
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
 | 
						|
                unordered_detail::reset(constructed_);
 | 
						|
                unordered_detail::reset(ptr_);
 | 
						|
#endif
 | 
						|
            }
 | 
						|
 | 
						|
            ~allocator_array_constructor() {
 | 
						|
                if (ptr_) {
 | 
						|
                    for(pointer p = ptr_; p != constructed_; ++p)
 | 
						|
                        alloc_.destroy(p);
 | 
						|
 | 
						|
                    alloc_.deallocate(ptr_, length_);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            template <class V>
 | 
						|
            void construct(V const& v, std::size_t l)
 | 
						|
            {
 | 
						|
                BOOST_ASSERT(!ptr_);
 | 
						|
                length_ = l;
 | 
						|
                ptr_ = alloc_.allocate(length_);
 | 
						|
                pointer end = ptr_ + length_;
 | 
						|
                for(constructed_ = ptr_; constructed_ != end; ++constructed_)
 | 
						|
                    alloc_.construct(constructed_, v);
 | 
						|
            }
 | 
						|
 | 
						|
            pointer get() const
 | 
						|
            {
 | 
						|
                return ptr_;
 | 
						|
            }
 | 
						|
 | 
						|
            pointer release()
 | 
						|
            {
 | 
						|
                pointer p(ptr_);
 | 
						|
                reset(ptr_);
 | 
						|
                return p;
 | 
						|
            }
 | 
						|
        private:
 | 
						|
            allocator_array_constructor(allocator_array_constructor const&);
 | 
						|
            allocator_array_constructor& operator=(allocator_array_constructor const&);
 | 
						|
        };
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#if defined(BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES)
 | 
						|
#  undef BOOST_UNORDERED_USE_ALLOCATOR_UTILITIES
 | 
						|
#endif
 | 
						|
 | 
						|
#endif
 |