forked from boostorg/detail
allocator_utilities.hpp: added partial_std_allocator_wrapper::value_type
composite_key.hpp: used hash_fwd.hpp
auto_space.hpp: added support for non-standard allocators
bidir_node_iterator.hpp: moved friend-injected operators out of class
copy_map.hpp: added support for non-standard allocators
hash_index_args.hpp: removed deprecated use of <boost/functional/hash/hash.hpp>
hash_index_iterator.hpp: moved friend-injected operators our of class
hash_index_node.hpp: added support for non-standard allocators
header_holder.hpp:added support for non-standard allocators
index_base.hpp: added support for non-standard allocators, added modify_rollback, added small improvement to modify
index_loader.hpp: added support for non-standard allocators
index_matcher.hpp: added support for non-standard allocators
index_node_base.hpp: added support for non-standard allocators
iter_adaptor.hpp: added some out-of-class operators to alleviate a MSVC++ 6.0 problem
modify_key_adaptor.hpp: renamed some vars to accomudate broader usage scope
node_type.hpp: added support for non-standard allocators
ord_index_node.hpp: added support for non-standard allocators
ord_index_ops.hpp: implemented a more efficient equal_range
rnd_index_loader.hpp: added support for non-standard allocators
rnd_index_node.hpp: added support for non-standard allocators
rnd_index_ops.hpp: added support for non-standard allocators
rnd_index_ptr_array.hpp: added support for non-standard allocators
rnd_node_iterator.hpp: moved friend-injected operators out of class
seq_index_node.hpp: added support for non-standard allocators
seq_index_ops.hpp: added support for non-standard allocators
uintptr_type.hpp: added support for __int64
unbounded.hpp: fixed ODR problem
value_compare.hpp: fixed a small unefficiency
global_fun: initial commit
hashed_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, [local_]iterator_to, rollback modify
identity_fwd.hpp: fixed wrong include guard name
key_extractors.hpp: added global_fun
mem_fun.hpp: removed superfluous =0's
ordered_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, improved equal_range and range, added conformance to DR 233
random_access_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, added conformance to 23.1.1/9
sequenced_index.hpp: added support for non-standard allocators, added c[r]{begin|end}, iterator_to, rollback modify, added conformance to 23.1.1/9, improved resize
multi_index_container.hpp: added support for non-standard allocators, improved ctor_args_list, rollback modify
acknowledgements.html: added entry for Boost 1.35
examples.html: renamed example 2, added B.IP example/composite_keys.cpp
future_work.html: removed entry on bimap
hash_indices.html: added c[r]{begin|end}, [local_]iterator_to, rollback modify
reference/index.html: added global_fun
reference/key_extraction.html: added global_fun, added technical correction
multi_index_container.html: added support for non-standard allocators
ord_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
rnd_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
seq_indices.html: added c[r]{begin|end}, iterator_to, rollback modify
release_notes.html: added entry for Boost 1.35
tests.html: added new serialization test file
basics.html: added rollback modify
creation.html: added support for non-standard allocators
tutorial/indices.html: added iterator_to
tutorial/key_extraction.html: added global_fun
composite_keys.cpp: fixed technicality
fun_key.cpp: was memfun_key.cpp, added global_fun
ip_allocator.cpp: initial commit
example/Jamfile.v2: renamed memfun_key, added ip_allocator
test_perf.cpp: fixed technicality
employee.hpp: used a non-standard allocator
test/Jamfile.v2: added new test file
non_std_allocator.hpp: initial commit
pair_of_ints.hpp: added decrement facilities
test_capacity.cpp: added extra check on resize
test_copy_assignment.cpp: added test for 23.1.1/9
test_iterators.cpp: added tests for c[r]{begin|end} and [local_]iterator_to, fixed technicality
test_key_extractors.cpp: added tests for global_fun
test_modifiers.cpp: added tests dor DR 233, fixed technicality
test_range.cpp: added extra checks to secure range refactoring
test_rearrange.cpp: fixed technicality
test_serialization.cpp: added new test file
test_serialization1.cpp: corrected include, used a non-standard allocator
test_serialization2.cpp: corrected include, used a non-standard allocator, split some stuff ro test_serialization3.cpp
test_serialization3.cpp: initial commit
test_serialization3.hpp: initial commit
test_serialization_template.hpp: removed some reliance on ADL
test_update.cpp: addes tests for rollback modify, fixed technicality
[SVN r39922]
194 lines
4.7 KiB
C++
194 lines
4.7 KiB
C++
/* Copyright 2003-2007 Joaquín M López Muñoz.
|
|
* Distributed under 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)
|
|
*
|
|
* See Boost website at http://www.boost.org/
|
|
*/
|
|
|
|
#ifndef BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
|
|
#define BOOST_DETAIL_ALLOCATOR_UTILITIES_HPP
|
|
|
|
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
#include <boost/detail/workaround.hpp>
|
|
#include <boost/mpl/aux_/msvc_never_true.hpp>
|
|
#include <boost/mpl/eval_if.hpp>
|
|
#include <boost/type_traits/is_same.hpp>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <new>
|
|
|
|
namespace boost{
|
|
|
|
namespace detail{
|
|
|
|
/* Allocator adaption layer. Some stdlibs provide allocators without rebind
|
|
* and template ctors. These facilities are simulated with the external
|
|
* template class rebind_to and the aid of partial_std_allocator_wrapper.
|
|
*/
|
|
|
|
namespace allocator{
|
|
|
|
/* partial_std_allocator_wrapper inherits the functionality of a std
|
|
* allocator while providing a templatized ctor and other bits missing
|
|
* in some stdlib implementation or another.
|
|
*/
|
|
|
|
template<typename Type>
|
|
class partial_std_allocator_wrapper:public std::allocator<Type>
|
|
{
|
|
public:
|
|
/* Oddly enough, STLport does not define std::allocator<void>::value_type
|
|
* when configured to work without partial template specialization.
|
|
* No harm in supplying the definition here unconditionally.
|
|
*/
|
|
|
|
typedef Type value_type;
|
|
|
|
partial_std_allocator_wrapper(){};
|
|
|
|
template<typename Other>
|
|
partial_std_allocator_wrapper(const partial_std_allocator_wrapper<Other>&){}
|
|
|
|
partial_std_allocator_wrapper(const std::allocator<Type>& x):
|
|
std::allocator<Type>(x)
|
|
{
|
|
};
|
|
|
|
#if defined(BOOST_DINKUMWARE_STDLIB)
|
|
/* Dinkumware guys didn't provide a means to call allocate() without
|
|
* supplying a hint, in disagreement with the standard.
|
|
*/
|
|
|
|
Type* allocate(std::size_t n,const void* hint=0)
|
|
{
|
|
std::allocator<Type>& a=*this;
|
|
return a.allocate(n,hint);
|
|
}
|
|
#endif
|
|
|
|
};
|
|
|
|
/* Detects whether a given allocator belongs to a defective stdlib not
|
|
* having the required member templates.
|
|
* Note that it does not suffice to check the Boost.Config stdlib
|
|
* macros, as the user might have passed a custom, compliant allocator.
|
|
* The checks also considers partial_std_allocator_wrapper to be
|
|
* a standard defective allocator.
|
|
*/
|
|
|
|
#if defined(BOOST_NO_STD_ALLOCATOR)&&\
|
|
(defined(BOOST_HAS_PARTIAL_STD_ALLOCATOR)||defined(BOOST_DINKUMWARE_STDLIB))
|
|
|
|
template<typename Allocator>
|
|
struct is_partial_std_allocator
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool,
|
|
value=
|
|
(is_same<
|
|
std::allocator<BOOST_DEDUCED_TYPENAME Allocator::value_type>,
|
|
Allocator
|
|
>::value)||
|
|
(is_same<
|
|
partial_std_allocator_wrapper<
|
|
BOOST_DEDUCED_TYPENAME Allocator::value_type>,
|
|
Allocator
|
|
>::value));
|
|
};
|
|
|
|
#else
|
|
|
|
template<typename Allocator>
|
|
struct is_partial_std_allocator
|
|
{
|
|
BOOST_STATIC_CONSTANT(bool,value=false);
|
|
};
|
|
|
|
#endif
|
|
|
|
/* rebind operations for defective std allocators */
|
|
|
|
template<typename Allocator,typename Type>
|
|
struct partial_std_allocator_rebind_to
|
|
{
|
|
typedef partial_std_allocator_wrapper<Type> type;
|
|
};
|
|
|
|
/* rebind operation in all other cases */
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
|
/* Workaround for a problem in MSVC with dependent template typedefs
|
|
* when doing rebinding of allocators.
|
|
* Modeled after <boost/mpl/aux_/msvc_dtw.hpp> (thanks, Aleksey!)
|
|
*/
|
|
|
|
template<typename Allocator>
|
|
struct rebinder
|
|
{
|
|
template<bool> struct fake_allocator:Allocator{};
|
|
template<> struct fake_allocator<true>
|
|
{
|
|
template<typename Type> struct rebind{};
|
|
};
|
|
|
|
template<typename Type>
|
|
struct result:
|
|
fake_allocator<mpl::aux::msvc_never_true<Allocator>::value>::
|
|
template rebind<Type>
|
|
{
|
|
};
|
|
};
|
|
#else
|
|
template<typename Allocator>
|
|
struct rebinder
|
|
{
|
|
template<typename Type>
|
|
struct result
|
|
{
|
|
typedef typename Allocator::BOOST_NESTED_TEMPLATE
|
|
rebind<Type>::other other;
|
|
};
|
|
};
|
|
#endif
|
|
|
|
template<typename Allocator,typename Type>
|
|
struct compliant_allocator_rebind_to
|
|
{
|
|
typedef typename rebinder<Allocator>::
|
|
BOOST_NESTED_TEMPLATE result<Type>::other type;
|
|
};
|
|
|
|
/* rebind front-end */
|
|
|
|
template<typename Allocator,typename Type>
|
|
struct rebind_to:
|
|
mpl::eval_if_c<
|
|
is_partial_std_allocator<Allocator>::value,
|
|
partial_std_allocator_rebind_to<Allocator,Type>,
|
|
compliant_allocator_rebind_to<Allocator,Type>
|
|
>
|
|
{
|
|
};
|
|
|
|
/* allocator-independent versions of construct and destroy */
|
|
|
|
template<typename Type>
|
|
void construct(void* p,const Type& t)
|
|
{
|
|
new (p) Type(t);
|
|
}
|
|
|
|
template<typename Type>
|
|
void destroy(const Type* p)
|
|
{
|
|
p->~Type();
|
|
}
|
|
|
|
} /* namespace boost::detail::allocator */
|
|
|
|
} /* namespace boost::detail */
|
|
|
|
} /* namespace boost */
|
|
|
|
#endif
|