mirror of https://github.com/trapexit/mergerfs.git
Antonio SJ Musumeci
8 months ago
316 changed files with 8 additions and 104104 deletions
-
69src/boost/bind/arg.hpp
-
2346src/boost/bind/bind.hpp
-
117src/boost/bind/bind_cc.hpp
-
228src/boost/bind/bind_mf2_cc.hpp
-
441src/boost/bind/bind_mf_cc.hpp
-
345src/boost/bind/bind_template.hpp
-
36src/boost/bind/detail/is_same.hpp
-
165src/boost/bind/detail/result_traits.hpp
-
74src/boost/bind/placeholders.hpp
-
40src/boost/bind/std_placeholders.hpp
-
476src/boost/bind/storage.hpp
-
502src/boost/container/allocator_traits.hpp
-
388src/boost/container/container_fwd.hpp
-
33src/boost/container/detail/addressof.hpp
-
542src/boost/container/detail/advanced_insert_int.hpp
-
185src/boost/container/detail/algorithm.hpp
-
60src/boost/container/detail/alloc_helpers.hpp
-
58src/boost/container/detail/allocation_type.hpp
-
162src/boost/container/detail/allocator_version_traits.hpp
-
134src/boost/container/detail/compare_functors.hpp
-
61src/boost/container/detail/config_begin.hpp
-
16src/boost/container/detail/config_end.hpp
-
98src/boost/container/detail/construct_in_place.hpp
-
53src/boost/container/detail/container_or_allocator_rebind.hpp
-
163src/boost/container/detail/container_rebind.hpp
-
1982src/boost/container/detail/copy_move_algo.hpp
-
502src/boost/container/detail/destroyers.hpp
-
1711src/boost/container/detail/flat_tree.hpp
-
72src/boost/container/detail/is_container.hpp
-
82src/boost/container/detail/is_contiguous_container.hpp
-
91src/boost/container/detail/is_pair.hpp
-
57src/boost/container/detail/is_sorted.hpp
-
94src/boost/container/detail/iterator.hpp
-
910src/boost/container/detail/iterators.hpp
-
37src/boost/container/detail/min_max.hpp
-
32src/boost/container/detail/minimal_char_traits_header.hpp
-
144src/boost/container/detail/mpl.hpp
-
307src/boost/container/detail/multiallocation_chain.hpp
-
98src/boost/container/detail/next_capacity.hpp
-
604src/boost/container/detail/node_alloc_holder.hpp
-
607src/boost/container/detail/pair.hpp
-
55src/boost/container/detail/pair_key_mapped_of_value.hpp
-
24src/boost/container/detail/placement_new.hpp
-
62src/boost/container/detail/std_fwd.hpp
-
180src/boost/container/detail/transform_iterator.hpp
-
1437src/boost/container/detail/tree.hpp
-
75src/boost/container/detail/type_traits.hpp
-
32src/boost/container/detail/value_functors.hpp
-
51src/boost/container/detail/value_init.hpp
-
163src/boost/container/detail/variadic_templates_tools.hpp
-
101src/boost/container/detail/version_type.hpp
-
190src/boost/container/detail/workaround.hpp
-
3067src/boost/container/flat_map.hpp
-
2315src/boost/container/map.hpp
-
201src/boost/container/new_allocator.hpp
-
445src/boost/container/node_handle.hpp
-
671src/boost/container/options.hpp
-
3625src/boost/container/string.hpp
-
295src/boost/container/throw_exception.hpp
-
3188src/boost/container/vector.hpp
-
17src/boost/core/use_default.hpp
-
193src/boost/detail/allocator_utilities.hpp
-
195src/boost/detail/indirect_traits.hpp
-
273src/boost/detail/interlocked.hpp
-
36src/boost/detail/select_type.hpp
-
18src/boost/flyweight.hpp
-
116src/boost/flyweight/assoc_container_factory.hpp
-
35src/boost/flyweight/assoc_container_factory_fwd.hpp
-
79src/boost/flyweight/detail/archive_constructed.hpp
-
65src/boost/flyweight/detail/is_placeholder_expr.hpp
-
39src/boost/flyweight/detail/nested_xxx_if_not_ph.hpp
-
98src/boost/flyweight/detail/serialization_helper.hpp
-
54src/boost/flyweight/intermodule_holder.hpp
-
29src/boost/flyweight/intermodule_holder_fwd.hpp
-
301src/boost/flyweight/key_value.hpp
-
29src/boost/flyweight/key_value_fwd.hpp
-
36src/boost/flyweight/no_locking.hpp
-
46src/boost/flyweight/no_tracking.hpp
-
26src/boost/flyweight/no_tracking_fwd.hpp
-
97src/boost/flyweight/serialize.hpp
-
82src/boost/flyweight/set_factory.hpp
-
40src/boost/flyweight/set_factory_fwd.hpp
-
580src/boost/integer/common_factor_rt.hpp
-
307src/boost/interprocess/allocators/allocator.hpp
-
857src/boost/interprocess/allocators/detail/allocator_common.hpp
-
44src/boost/interprocess/containers/allocation_type.hpp
-
37src/boost/interprocess/containers/version_type.hpp
-
85src/boost/interprocess/creation_tags.hpp
-
674src/boost/interprocess/detail/atomic.hpp
-
31src/boost/interprocess/detail/cast_tags.hpp
-
127src/boost/interprocess/detail/char_wchar_holder.hpp
-
50src/boost/interprocess/detail/config_begin.hpp
-
16src/boost/interprocess/detail/config_end.hpp
-
23src/boost/interprocess/detail/config_external_begin.hpp
-
12src/boost/interprocess/detail/config_external_end.hpp
-
302src/boost/interprocess/detail/file_locking_helpers.hpp
-
77src/boost/interprocess/detail/in_place_interface.hpp
-
53src/boost/interprocess/detail/intermodule_singleton.hpp
-
505src/boost/interprocess/detail/intermodule_singleton_common.hpp
-
39src/boost/interprocess/detail/interprocess_tester.hpp
@ -1,69 +0,0 @@ |
|||||
#ifndef BOOST_BIND_ARG_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_ARG_HPP_INCLUDED
|
|
||||
|
|
||||
// MS compatible compilers support #pragma once
|
|
||||
|
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//
|
|
||||
// bind/arg.hpp
|
|
||||
//
|
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
#include <boost/config.hpp>
|
|
||||
#include <boost/is_placeholder.hpp>
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
template<bool Eq> struct _arg_eq |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template<> struct _arg_eq<true> |
|
||||
{ |
|
||||
typedef void type; |
|
||||
}; |
|
||||
|
|
||||
template< int I > struct arg |
|
||||
{ |
|
||||
BOOST_CONSTEXPR arg() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
template< class T > BOOST_CONSTEXPR arg( T const & /* t */, typename _arg_eq< I == is_placeholder<T>::value >::type * = 0 ) |
|
||||
{ |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template< int I > BOOST_CONSTEXPR bool operator==( arg<I> const &, arg<I> const & ) |
|
||||
{ |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template< int I > struct is_placeholder< arg<I> > |
|
||||
{ |
|
||||
enum _vt { value = I }; |
|
||||
}; |
|
||||
|
|
||||
template< int I > struct is_placeholder< arg<I> (*) () > |
|
||||
{ |
|
||||
enum _vt { value = I }; |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED
|
|
2346
src/boost/bind/bind.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,117 +0,0 @@ |
|||||
//
|
|
||||
// bind/bind_cc.hpp - support for different calling conventions
|
|
||||
//
|
|
||||
// Do not include this header directly.
|
|
||||
//
|
|
||||
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
template<class R> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) () BOOST_BIND_NOEXCEPT, _bi::list0> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) () BOOST_BIND_NOEXCEPT) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) () BOOST_BIND_NOEXCEPT; |
|
||||
typedef _bi::list0 list_type; |
|
||||
return _bi::bind_t<R, F, list_type> (f, list_type()); |
|
||||
} |
|
||||
|
|
||||
template<class R, class B1, class A1> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1) BOOST_BIND_NOEXCEPT, typename _bi::list_av_1<A1>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1) BOOST_BIND_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type> (f, list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class B1, class B2, class A1, class A2> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2) BOOST_BIND_NOEXCEPT, typename _bi::list_av_2<A1, A2>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type> (f, list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3) BOOST_BIND_NOEXCEPT, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
template<class R, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, class B9, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
_bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
@ -1,228 +0,0 @@ |
|||||
//
|
|
||||
// bind/bind_mf2_cc.hpp - member functions, type<> syntax
|
|
||||
//
|
|
||||
// Do not include this header directly.
|
|
||||
//
|
|
||||
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
|
||||
// Copyright (c) 2008 Peter Dimov
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
// 0
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class A1> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class A1> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
// 1
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
// 2
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
// 3
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
// 4
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
// 5
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
// 6
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
// 7
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
// 8
|
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
@ -1,441 +0,0 @@ |
|||||
//
|
|
||||
// bind/bind_mf_cc.hpp - support for different calling conventions
|
|
||||
//
|
|
||||
// Do not include this header directly.
|
|
||||
//
|
|
||||
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
// 0
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class A1> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class A1> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class A1> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class A1> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F; |
|
||||
typedef typename _bi::list_av_1<A1>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1)); |
|
||||
} |
|
||||
|
|
||||
// 1
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, |
|
||||
class A1, class A2> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F; |
|
||||
typedef typename _bi::list_av_2<A1, A2>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2)); |
|
||||
} |
|
||||
|
|
||||
// 2
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, |
|
||||
class A1, class A2, class A3> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F; |
|
||||
typedef typename _bi::list_av_3<A1, A2, A3>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3)); |
|
||||
} |
|
||||
|
|
||||
// 3
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, |
|
||||
class A1, class A2, class A3, class A4> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F; |
|
||||
typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4)); |
|
||||
} |
|
||||
|
|
||||
// 4
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, |
|
||||
class A1, class A2, class A3, class A4, class A5> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F; |
|
||||
typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5)); |
|
||||
} |
|
||||
|
|
||||
// 5
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F; |
|
||||
typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6)); |
|
||||
} |
|
||||
|
|
||||
// 6
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F; |
|
||||
typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); |
|
||||
} |
|
||||
|
|
||||
// 7
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F; |
|
||||
typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); |
|
||||
} |
|
||||
|
|
||||
// 8
|
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
||||
|
|
||||
template<class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
_bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
||||
|
|
||||
template<class Rt2, class R, class T, |
|
||||
class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, |
|
||||
class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> |
|
||||
typename boost::enable_if_c<!_bi::is_same<Rt2, R>::value, |
|
||||
_bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type> |
|
||||
>::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) |
|
||||
{ |
|
||||
typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F; |
|
||||
typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type; |
|
||||
return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); |
|
||||
} |
|
@ -1,345 +0,0 @@ |
|||||
//
|
|
||||
// bind/bind_template.hpp
|
|
||||
//
|
|
||||
// Do not include this header directly.
|
|
||||
//
|
|
||||
// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
typedef typename result_traits<R, F>::type result_type; |
|
||||
|
|
||||
result_type operator()() |
|
||||
{ |
|
||||
list0 a; |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
result_type operator()() const |
|
||||
{ |
|
||||
list0 a; |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1> result_type operator()(A1 & a1) |
|
||||
{ |
|
||||
list1<A1 &> a(a1); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1> result_type operator()(A1 & a1) const |
|
||||
{ |
|
||||
list1<A1 &> a(a1); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1> result_type operator()(A1 const & a1) |
|
||||
{ |
|
||||
list1<A1 const &> a(a1); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1> result_type operator()(A1 const & a1) const |
|
||||
{ |
|
||||
list1<A1 const &> a(a1); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2) |
|
||||
{ |
|
||||
list2<A1 &, A2 &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2) const |
|
||||
{ |
|
||||
list2<A1 &, A2 &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2) |
|
||||
{ |
|
||||
list2<A1 const &, A2 &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2) const |
|
||||
{ |
|
||||
list2<A1 const &, A2 &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2) |
|
||||
{ |
|
||||
list2<A1 &, A2 const &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2) const |
|
||||
{ |
|
||||
list2<A1 &, A2 const &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2) |
|
||||
{ |
|
||||
list2<A1 const &, A2 const &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2) const |
|
||||
{ |
|
||||
list2<A1 const &, A2 const &> a(a1, a2); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3> result_type operator()(A1 & a1, A2 & a2, A3 & a3) |
|
||||
{ |
|
||||
list3<A1 &, A2 &, A3 &> a(a1, a2, a3); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3> result_type operator()(A1 & a1, A2 & a2, A3 & a3) const |
|
||||
{ |
|
||||
list3<A1 &, A2 &, A3 &> a(a1, a2, a3); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) |
|
||||
{ |
|
||||
list3<A1 const &, A2 const &, A3 const &> a(a1, a2, a3); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) const |
|
||||
{ |
|
||||
list3<A1 const &, A2 const &, A3 const &> a(a1, a2, a3); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) |
|
||||
{ |
|
||||
list4<A1 &, A2 &, A3 &, A4 &> a(a1, a2, a3, a4); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) const |
|
||||
{ |
|
||||
list4<A1 &, A2 &, A3 &, A4 &> a(a1, a2, a3, a4); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) |
|
||||
{ |
|
||||
list4<A1 const &, A2 const &, A3 const &, A4 const &> a(a1, a2, a3, a4); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) const |
|
||||
{ |
|
||||
list4<A1 const &, A2 const &, A3 const &, A4 const &> a(a1, a2, a3, a4); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) |
|
||||
{ |
|
||||
list5<A1 &, A2 &, A3 &, A4 &, A5 &> a(a1, a2, a3, a4, a5); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const |
|
||||
{ |
|
||||
list5<A1 &, A2 &, A3 &, A4 &, A5 &> a(a1, a2, a3, a4, a5); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) |
|
||||
{ |
|
||||
list5<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &> a(a1, a2, a3, a4, a5); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) const |
|
||||
{ |
|
||||
list5<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &> a(a1, a2, a3, a4, a5); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) |
|
||||
{ |
|
||||
list6<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &> a(a1, a2, a3, a4, a5, a6); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const |
|
||||
{ |
|
||||
list6<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &> a(a1, a2, a3, a4, a5, a6); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) |
|
||||
{ |
|
||||
list6<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &> a(a1, a2, a3, a4, a5, a6); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) const |
|
||||
{ |
|
||||
list6<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &> a(a1, a2, a3, a4, a5, a6); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) |
|
||||
{ |
|
||||
list7<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &> a(a1, a2, a3, a4, a5, a6, a7); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const |
|
||||
{ |
|
||||
list7<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &> a(a1, a2, a3, a4, a5, a6, a7); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) |
|
||||
{ |
|
||||
list7<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &> a(a1, a2, a3, a4, a5, a6, a7); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) const |
|
||||
{ |
|
||||
list7<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &> a(a1, a2, a3, a4, a5, a6, a7); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) |
|
||||
{ |
|
||||
list8<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &> a(a1, a2, a3, a4, a5, a6, a7, a8); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const |
|
||||
{ |
|
||||
list8<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &> a(a1, a2, a3, a4, a5, a6, a7, a8); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) |
|
||||
{ |
|
||||
list8<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &> a(a1, a2, a3, a4, a5, a6, a7, a8); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) const |
|
||||
{ |
|
||||
list8<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &> a(a1, a2, a3, a4, a5, a6, a7, a8); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) |
|
||||
{ |
|
||||
list9<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &, A9 &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const |
|
||||
{ |
|
||||
list9<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &, A9 &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
|
|
||||
&& !BOOST_WORKAROUND(__EDG_VERSION__, <= 238) |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) |
|
||||
{ |
|
||||
list9<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &, A9 const &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) const |
|
||||
{ |
|
||||
list9<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &, A9 const &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9); |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template<class A> result_type eval(A & a) |
|
||||
{ |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class A> result_type eval(A & a) const |
|
||||
{ |
|
||||
BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0); |
|
||||
} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( BOOST_BORLANDC )
|
|
||||
|
|
||||
using boost::visit_each; |
|
||||
|
|
||||
#endif
|
|
||||
BOOST_BIND_VISIT_EACH(v, f_, 0); |
|
||||
l_.accept(v); |
|
||||
} |
|
||||
|
|
||||
bool compare(this_type const & rhs) const |
|
||||
{ |
|
||||
return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
F f_; |
|
||||
L l_; |
|
@ -1,36 +0,0 @@ |
|||||
#ifndef BOOST_BIND_DETAIL_IS_SAME_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_DETAIL_IS_SAME_HPP_INCLUDED
|
|
||||
|
|
||||
// is_same<T1,T2>::value is true when T1 == T2
|
|
||||
//
|
|
||||
// Copyright 2014 Peter Dimov
|
|
||||
//
|
|
||||
// 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
|
|
||||
|
|
||||
#include <boost/config.hpp>
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
namespace _bi |
|
||||
{ |
|
||||
|
|
||||
template< class T1, class T2 > struct is_same |
|
||||
{ |
|
||||
BOOST_STATIC_CONSTANT( bool, value = false ); |
|
||||
}; |
|
||||
|
|
||||
template< class T > struct is_same< T, T > |
|
||||
{ |
|
||||
BOOST_STATIC_CONSTANT( bool, value = true ); |
|
||||
}; |
|
||||
|
|
||||
} // namespace _bi
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_DETAIL_IS_SAME_HPP_INCLUDED
|
|
@ -1,165 +0,0 @@ |
|||||
#ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED
|
|
||||
|
|
||||
// MS compatible compilers support #pragma once
|
|
||||
|
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//
|
|
||||
// bind/detail/result_traits.hpp
|
|
||||
//
|
|
||||
// boost/bind.hpp support header, return type deduction
|
|
||||
//
|
|
||||
// Copyright 2006, 2020 Peter Dimov
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
#include <boost/config.hpp>
|
|
||||
#include <boost/core/ref.hpp>
|
|
||||
|
|
||||
#if BOOST_CXX_VERSION >= 201700L
|
|
||||
#include <functional>
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
namespace _bi |
|
||||
{ |
|
||||
|
|
||||
template<class R, class F> struct result_traits |
|
||||
{ |
|
||||
typedef R type; |
|
||||
}; |
|
||||
|
|
||||
struct unspecified {}; |
|
||||
|
|
||||
template<class F> struct result_traits<unspecified, F> |
|
||||
{ |
|
||||
typedef typename F::result_type type; |
|
||||
}; |
|
||||
|
|
||||
template<class F> struct result_traits< unspecified, reference_wrapper<F> > |
|
||||
{ |
|
||||
typedef typename F::result_type type; |
|
||||
}; |
|
||||
|
|
||||
#if BOOST_CXX_VERSION >= 201700L
|
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::plus<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::minus<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::multiplies<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::divides<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::modulus<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::negate<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::equal_to<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::not_equal_to<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::greater<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::less<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::greater_equal<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::less_equal<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::logical_and<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::logical_or<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::logical_not<T> > |
|
||||
{ |
|
||||
typedef bool type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::bit_and<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::bit_or<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::bit_xor<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 40900
|
|
||||
|
|
||||
// libstdc++ 4.8 and below don't have std::bit_not
|
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
template<class T> struct result_traits< unspecified, std::bit_not<T> > |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} // namespace _bi
|
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED
|
|
@ -1,74 +0,0 @@ |
|||||
#ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
|
|
||||
|
|
||||
// MS compatible compilers support #pragma once
|
|
||||
|
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//
|
|
||||
// bind/placeholders.hpp - _N definitions
|
|
||||
//
|
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
|
||||
// Copyright 2015 Peter Dimov
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
#include <boost/bind/arg.hpp>
|
|
||||
#include <boost/config.hpp>
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
namespace placeholders |
|
||||
{ |
|
||||
|
|
||||
#if defined(BOOST_BORLANDC) || defined(__GNUC__) && (__GNUC__ < 4)
|
|
||||
|
|
||||
inline boost::arg<1> _1() { return boost::arg<1>(); } |
|
||||
inline boost::arg<2> _2() { return boost::arg<2>(); } |
|
||||
inline boost::arg<3> _3() { return boost::arg<3>(); } |
|
||||
inline boost::arg<4> _4() { return boost::arg<4>(); } |
|
||||
inline boost::arg<5> _5() { return boost::arg<5>(); } |
|
||||
inline boost::arg<6> _6() { return boost::arg<6>(); } |
|
||||
inline boost::arg<7> _7() { return boost::arg<7>(); } |
|
||||
inline boost::arg<8> _8() { return boost::arg<8>(); } |
|
||||
inline boost::arg<9> _9() { return boost::arg<9>(); } |
|
||||
|
|
||||
#elif !defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
|
||||
|
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<1> _1; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<2> _2; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<3> _3; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<4> _4; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<5> _5; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<6> _6; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<7> _7; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<8> _8; |
|
||||
BOOST_INLINE_CONSTEXPR boost::arg<9> _9; |
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<1> _1; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<2> _2; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<3> _3; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<4> _4; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<5> _5; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<6> _6; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<7> _7; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<8> _8; |
|
||||
BOOST_STATIC_CONSTEXPR boost::arg<9> _9; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} // namespace placeholders
|
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
|
|
@ -1,40 +0,0 @@ |
|||||
#ifndef BOOST_BIND_STD_PLACEHOLDERS_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_STD_PLACEHOLDERS_HPP_INCLUDED
|
|
||||
|
|
||||
// MS compatible compilers support #pragma once
|
|
||||
|
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
// Copyright 2021 Peter Dimov
|
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
|
||||
|
|
||||
#include <boost/bind/detail/requires_cxx11.hpp>
|
|
||||
#include <boost/is_placeholder.hpp>
|
|
||||
#include <boost/config.hpp>
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS)
|
|
||||
|
|
||||
#include <functional>
|
|
||||
#include <type_traits>
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_1)>::type > { enum _vt { value = 1 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_2)>::type > { enum _vt { value = 2 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_3)>::type > { enum _vt { value = 3 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_4)>::type > { enum _vt { value = 4 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_5)>::type > { enum _vt { value = 5 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_6)>::type > { enum _vt { value = 6 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_7)>::type > { enum _vt { value = 7 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_8)>::type > { enum _vt { value = 8 }; }; |
|
||||
template<> struct is_placeholder< typename std::decay<decltype(std::placeholders::_9)>::type > { enum _vt { value = 9 }; }; |
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_STD_PLACEHOLDERS_HPP_INCLUDED
|
|
@ -1,476 +0,0 @@ |
|||||
#ifndef BOOST_BIND_STORAGE_HPP_INCLUDED
|
|
||||
#define BOOST_BIND_STORAGE_HPP_INCLUDED
|
|
||||
|
|
||||
// MS compatible compilers support #pragma once
|
|
||||
|
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//
|
|
||||
// bind/storage.hpp
|
|
||||
//
|
|
||||
// boost/bind.hpp support header, optimized storage
|
|
||||
//
|
|
||||
// Copyright (c) 2006 Peter Dimov
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/bind/bind.html for documentation.
|
|
||||
//
|
|
||||
|
|
||||
#include <boost/bind/detail/requires_cxx11.hpp>
|
|
||||
#include <boost/config.hpp>
|
|
||||
#include <boost/bind/arg.hpp>
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
# pragma warning(push)
|
|
||||
# pragma warning(disable: 4512) // assignment operator could not be generated
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
namespace _bi |
|
||||
{ |
|
||||
|
|
||||
// 1
|
|
||||
|
|
||||
template<class A1> struct storage1 |
|
||||
{ |
|
||||
explicit storage1( A1 a1 ): a1_( a1 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
BOOST_BIND_VISIT_EACH(v, a1_, 0); |
|
||||
} |
|
||||
|
|
||||
A1 a1_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_BORLANDC )
|
|
||||
|
|
||||
template<int I> struct storage1< boost::arg<I> > |
|
||||
{ |
|
||||
explicit storage1( boost::arg<I> ) {} |
|
||||
|
|
||||
template<class V> void accept(V &) const { } |
|
||||
|
|
||||
static boost::arg<I> a1_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<int I> struct storage1< boost::arg<I> (*) () > |
|
||||
{ |
|
||||
explicit storage1( boost::arg<I> (*) () ) {} |
|
||||
|
|
||||
template<class V> void accept(V &) const { } |
|
||||
|
|
||||
static boost::arg<I> a1_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 2
|
|
||||
|
|
||||
template<class A1, class A2> struct storage2: public storage1<A1> |
|
||||
{ |
|
||||
typedef storage1<A1> inherited; |
|
||||
|
|
||||
storage2( A1 a1, A2 a2 ): storage1<A1>( a1 ), a2_( a2 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a2_, 0); |
|
||||
} |
|
||||
|
|
||||
A2 a2_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, int I> struct storage2< A1, boost::arg<I> >: public storage1<A1> |
|
||||
{ |
|
||||
typedef storage1<A1> inherited; |
|
||||
|
|
||||
storage2( A1 a1, boost::arg<I> ): storage1<A1>( a1 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a2_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, int I> struct storage2< A1, boost::arg<I> (*) () >: public storage1<A1> |
|
||||
{ |
|
||||
typedef storage1<A1> inherited; |
|
||||
|
|
||||
storage2( A1 a1, boost::arg<I> (*) () ): storage1<A1>( a1 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a2_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 3
|
|
||||
|
|
||||
template<class A1, class A2, class A3> struct storage3: public storage2< A1, A2 > |
|
||||
{ |
|
||||
typedef storage2<A1, A2> inherited; |
|
||||
|
|
||||
storage3( A1 a1, A2 a2, A3 a3 ): storage2<A1, A2>( a1, a2 ), a3_( a3 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a3_, 0); |
|
||||
} |
|
||||
|
|
||||
A3 a3_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, int I> struct storage3< A1, A2, boost::arg<I> >: public storage2< A1, A2 > |
|
||||
{ |
|
||||
typedef storage2<A1, A2> inherited; |
|
||||
|
|
||||
storage3( A1 a1, A2 a2, boost::arg<I> ): storage2<A1, A2>( a1, a2 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a3_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, int I> struct storage3< A1, A2, boost::arg<I> (*) () >: public storage2< A1, A2 > |
|
||||
{ |
|
||||
typedef storage2<A1, A2> inherited; |
|
||||
|
|
||||
storage3( A1 a1, A2 a2, boost::arg<I> (*) () ): storage2<A1, A2>( a1, a2 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a3_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 4
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4> struct storage4: public storage3< A1, A2, A3 > |
|
||||
{ |
|
||||
typedef storage3<A1, A2, A3> inherited; |
|
||||
|
|
||||
storage4( A1 a1, A2 a2, A3 a3, A4 a4 ): storage3<A1, A2, A3>( a1, a2, a3 ), a4_( a4 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a4_, 0); |
|
||||
} |
|
||||
|
|
||||
A4 a4_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, int I> struct storage4< A1, A2, A3, boost::arg<I> >: public storage3< A1, A2, A3 > |
|
||||
{ |
|
||||
typedef storage3<A1, A2, A3> inherited; |
|
||||
|
|
||||
storage4( A1 a1, A2 a2, A3 a3, boost::arg<I> ): storage3<A1, A2, A3>( a1, a2, a3 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a4_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, int I> struct storage4< A1, A2, A3, boost::arg<I> (*) () >: public storage3< A1, A2, A3 > |
|
||||
{ |
|
||||
typedef storage3<A1, A2, A3> inherited; |
|
||||
|
|
||||
storage4( A1 a1, A2 a2, A3 a3, boost::arg<I> (*) () ): storage3<A1, A2, A3>( a1, a2, a3 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a4_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 5
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5> struct storage5: public storage4< A1, A2, A3, A4 > |
|
||||
{ |
|
||||
typedef storage4<A1, A2, A3, A4> inherited; |
|
||||
|
|
||||
storage5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ), a5_( a5 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a5_, 0); |
|
||||
} |
|
||||
|
|
||||
A5 a5_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, int I> struct storage5< A1, A2, A3, A4, boost::arg<I> >: public storage4< A1, A2, A3, A4 > |
|
||||
{ |
|
||||
typedef storage4<A1, A2, A3, A4> inherited; |
|
||||
|
|
||||
storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg<I> ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a5_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, int I> struct storage5< A1, A2, A3, A4, boost::arg<I> (*) () >: public storage4< A1, A2, A3, A4 > |
|
||||
{ |
|
||||
typedef storage4<A1, A2, A3, A4> inherited; |
|
||||
|
|
||||
storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg<I> (*) () ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a5_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 6
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6> struct storage6: public storage5< A1, A2, A3, A4, A5 > |
|
||||
{ |
|
||||
typedef storage5<A1, A2, A3, A4, A5> inherited; |
|
||||
|
|
||||
storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ), a6_( a6 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a6_, 0); |
|
||||
} |
|
||||
|
|
||||
A6 a6_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, int I> struct storage6< A1, A2, A3, A4, A5, boost::arg<I> >: public storage5< A1, A2, A3, A4, A5 > |
|
||||
{ |
|
||||
typedef storage5<A1, A2, A3, A4, A5> inherited; |
|
||||
|
|
||||
storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg<I> ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a6_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, int I> struct storage6< A1, A2, A3, A4, A5, boost::arg<I> (*) () >: public storage5< A1, A2, A3, A4, A5 > |
|
||||
{ |
|
||||
typedef storage5<A1, A2, A3, A4, A5> inherited; |
|
||||
|
|
||||
storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg<I> (*) () ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a6_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 7
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct storage7: public storage6< A1, A2, A3, A4, A5, A6 > |
|
||||
{ |
|
||||
typedef storage6<A1, A2, A3, A4, A5, A6> inherited; |
|
||||
|
|
||||
storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ), a7_( a7 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a7_, 0); |
|
||||
} |
|
||||
|
|
||||
A7 a7_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, int I> struct storage7< A1, A2, A3, A4, A5, A6, boost::arg<I> >: public storage6< A1, A2, A3, A4, A5, A6 > |
|
||||
{ |
|
||||
typedef storage6<A1, A2, A3, A4, A5, A6> inherited; |
|
||||
|
|
||||
storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg<I> ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a7_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, int I> struct storage7< A1, A2, A3, A4, A5, A6, boost::arg<I> (*) () >: public storage6< A1, A2, A3, A4, A5, A6 > |
|
||||
{ |
|
||||
typedef storage6<A1, A2, A3, A4, A5, A6> inherited; |
|
||||
|
|
||||
storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg<I> (*) () ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a7_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 8
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct storage8: public storage7< A1, A2, A3, A4, A5, A6, A7 > |
|
||||
{ |
|
||||
typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited; |
|
||||
|
|
||||
storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ), a8_( a8 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a8_, 0); |
|
||||
} |
|
||||
|
|
||||
A8 a8_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, int I> struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg<I> >: public storage7< A1, A2, A3, A4, A5, A6, A7 > |
|
||||
{ |
|
||||
typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited; |
|
||||
|
|
||||
storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg<I> ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a8_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, int I> struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg<I> (*) () >: public storage7< A1, A2, A3, A4, A5, A6, A7 > |
|
||||
{ |
|
||||
typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited; |
|
||||
|
|
||||
storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg<I> (*) () ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a8_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
// 9
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct storage9: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > |
|
||||
{ |
|
||||
typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited; |
|
||||
|
|
||||
storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ), a9_( a9 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
BOOST_BIND_VISIT_EACH(v, a9_, 0); |
|
||||
} |
|
||||
|
|
||||
A9 a9_; |
|
||||
}; |
|
||||
|
|
||||
#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
|
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, int I> struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg<I> >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > |
|
||||
{ |
|
||||
typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited; |
|
||||
|
|
||||
storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg<I> ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a9_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, int I> struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg<I> (*) () >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > |
|
||||
{ |
|
||||
typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited; |
|
||||
|
|
||||
storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg<I> (*) () ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ) {} |
|
||||
|
|
||||
template<class V> void accept(V & v) const |
|
||||
{ |
|
||||
inherited::accept(v); |
|
||||
} |
|
||||
|
|
||||
static boost::arg<I> a9_() { return boost::arg<I>(); } |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} // namespace _bi
|
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
# pragma warning(default: 4512) // assignment operator could not be generated
|
|
||||
# pragma warning(pop)
|
|
||||
#endif
|
|
||||
|
|
||||
#endif // #ifndef BOOST_BIND_STORAGE_HPP_INCLUDED
|
|
@ -1,502 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Pablo Halpern 2009. 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)
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
|
|
||||
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
// container
|
|
||||
#include <boost/container/container_fwd.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp> //is_empty
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
|
||||
#endif
|
|
||||
// intrusive
|
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
|
||||
// move
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
// move/detail
|
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
|
||||
#endif
|
|
||||
// other boost
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
|
||||
#endif
|
|
||||
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#endif
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
template<class T, class VoidAllocator, class Options> |
|
||||
class small_vector_allocator; |
|
||||
|
|
||||
namespace allocator_traits_detail { |
|
||||
|
|
||||
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size) |
|
||||
BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction) |
|
||||
|
|
||||
} //namespace allocator_traits_detail {
|
|
||||
|
|
||||
namespace dtl { |
|
||||
|
|
||||
//workaround needed for C++03 compilers with no construct()
|
|
||||
//supporting rvalue references
|
|
||||
template<class Allocator> |
|
||||
struct is_std_allocator |
|
||||
{ static const bool value = false; }; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_std_allocator< std::allocator<T> > |
|
||||
{ static const bool value = true; }; |
|
||||
|
|
||||
template<class T, class Options> |
|
||||
struct is_std_allocator< small_vector_allocator<T, std::allocator<T>, Options > > |
|
||||
{ static const bool value = true; }; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct is_not_std_allocator |
|
||||
{ static const bool value = !is_std_allocator<Allocator>::value; }; |
|
||||
|
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable) |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//! The class template allocator_traits supplies a uniform interface to all allocator types.
|
|
||||
//! This class is a C++03-compatible implementation of std::allocator_traits
|
|
||||
template <typename Allocator> |
|
||||
struct allocator_traits |
|
||||
{ |
|
||||
//allocator_type
|
|
||||
typedef Allocator allocator_type; |
|
||||
//value_type
|
|
||||
typedef typename allocator_type::value_type value_type; |
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
//! Allocator::pointer if such a type exists; otherwise, value_type*
|
|
||||
//!
|
|
||||
typedef unspecified pointer; |
|
||||
//! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
|
|
||||
//!
|
|
||||
typedef see_documentation const_pointer; |
|
||||
//! Non-standard extension
|
|
||||
//! Allocator::reference if such a type exists; otherwise, value_type&
|
|
||||
typedef see_documentation reference; |
|
||||
//! Non-standard extension
|
|
||||
//! Allocator::const_reference if such a type exists ; otherwise, const value_type&
|
|
||||
typedef see_documentation const_reference; |
|
||||
//! Allocator::void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<void>.
|
|
||||
//!
|
|
||||
typedef see_documentation void_pointer; |
|
||||
//! Allocator::const_void_pointer if such a type exists ; otherwise, pointer_traits<pointer>::rebind<const
|
|
||||
//!
|
|
||||
typedef see_documentation const_void_pointer; |
|
||||
//! Allocator::difference_type if such a type exists ; otherwise, pointer_traits<pointer>::difference_type.
|
|
||||
//!
|
|
||||
typedef see_documentation difference_type; |
|
||||
//! Allocator::size_type if such a type exists ; otherwise, make_unsigned<difference_type>::type
|
|
||||
//!
|
|
||||
typedef see_documentation size_type; |
|
||||
//! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type
|
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
|
||||
typedef see_documentation propagate_on_container_copy_assignment; |
|
||||
//! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type
|
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
|
||||
typedef see_documentation propagate_on_container_move_assignment; |
|
||||
//! Allocator::propagate_on_container_swap if such a type exists, otherwise a type
|
|
||||
//! with an internal constant static boolean member <code>value</code> == false.
|
|
||||
typedef see_documentation propagate_on_container_swap; |
|
||||
//! Allocator::is_always_equal if such a type exists, otherwise a type
|
|
||||
//! with an internal constant static boolean member <code>value</code> == is_empty<Allocator>::value
|
|
||||
typedef see_documentation is_always_equal; |
|
||||
//! Allocator::is_partially_propagable if such a type exists, otherwise a type
|
|
||||
//! with an internal constant static boolean member <code>value</code> == false
|
|
||||
//! <b>Note</b>: Non-standard extension used to implement `small_vector_allocator`.
|
|
||||
typedef see_documentation is_partially_propagable; |
|
||||
//! Defines an allocator: Allocator::rebind<T>::other if such a type exists; otherwise, Allocator<T, Args>
|
|
||||
//! if Allocator is a class template instantiation of the form Allocator<U, Args>, where Args is zero or
|
|
||||
//! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed.
|
|
||||
//!
|
|
||||
//! In C++03 compilers <code>rebind_alloc</code> is a struct derived from an allocator
|
|
||||
//! deduced by previously detailed rules.
|
|
||||
template <class T> using rebind_alloc = see_documentation; |
|
||||
|
|
||||
//! In C++03 compilers <code>rebind_traits</code> is a struct derived from
|
|
||||
//! <code>allocator_traits<OtherAlloc></code>, where <code>OtherAlloc</code> is
|
|
||||
//! the allocator deduced by rules explained in <code>rebind_alloc</code>.
|
|
||||
template <class T> using rebind_traits = allocator_traits<rebind_alloc<T> >; |
|
||||
|
|
||||
//! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers.
|
|
||||
//! <code>type</code> is an allocator related to Allocator deduced deduced by rules explained in <code>rebind_alloc</code>.
|
|
||||
template <class T> |
|
||||
struct portable_rebind_alloc |
|
||||
{ typedef see_documentation type; }; |
|
||||
#else
|
|
||||
//pointer
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
pointer, value_type*) |
|
||||
pointer; |
|
||||
//const_pointer
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
const_pointer, typename boost::intrusive::pointer_traits<pointer>::template |
|
||||
rebind_pointer<const value_type>) |
|
||||
const_pointer; |
|
||||
//reference
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
reference, typename dtl::unvoid_ref<value_type>::type) |
|
||||
reference; |
|
||||
//const_reference
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
const_reference, typename dtl::unvoid_ref<const value_type>::type) |
|
||||
const_reference; |
|
||||
//void_pointer
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
void_pointer, typename boost::intrusive::pointer_traits<pointer>::template |
|
||||
rebind_pointer<void>) |
|
||||
void_pointer; |
|
||||
//const_void_pointer
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
const_void_pointer, typename boost::intrusive::pointer_traits<pointer>::template |
|
||||
rebind_pointer<const void>) |
|
||||
const_void_pointer; |
|
||||
//difference_type
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
difference_type, std::ptrdiff_t) |
|
||||
difference_type; |
|
||||
//size_type
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
size_type, std::size_t) |
|
||||
size_type; |
|
||||
//propagate_on_container_copy_assignment
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
propagate_on_container_copy_assignment, dtl::false_type) |
|
||||
propagate_on_container_copy_assignment; |
|
||||
//propagate_on_container_move_assignment
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
propagate_on_container_move_assignment, dtl::false_type) |
|
||||
propagate_on_container_move_assignment; |
|
||||
//propagate_on_container_swap
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
propagate_on_container_swap, dtl::false_type) |
|
||||
propagate_on_container_swap; |
|
||||
//is_always_equal
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
is_always_equal, dtl::is_empty<Allocator>) |
|
||||
is_always_equal; |
|
||||
//is_partially_propagable
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, |
|
||||
is_partially_propagable, dtl::false_type) |
|
||||
is_partially_propagable; |
|
||||
|
|
||||
//rebind_alloc & rebind_traits
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
//C++11
|
|
||||
template <typename T> using rebind_alloc = typename boost::intrusive::pointer_rebind<Allocator, T>::type; |
|
||||
template <typename T> using rebind_traits = allocator_traits< rebind_alloc<T> >; |
|
||||
#else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
//Some workaround for C++03 or C++11 compilers with no template aliases
|
|
||||
template <typename T> |
|
||||
struct rebind_alloc : boost::intrusive::pointer_rebind<Allocator,T>::type |
|
||||
{ |
|
||||
typedef typename boost::intrusive::pointer_rebind<Allocator,T>::type Base; |
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
template <typename... Args> |
|
||||
rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward<Args>(args)...) {} |
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \
|
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ |
|
||||
explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC) |
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC
|
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
struct rebind_traits |
|
||||
: allocator_traits<typename boost::intrusive::pointer_rebind<Allocator, T>::type> |
|
||||
{}; |
|
||||
#endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//portable_rebind_alloc
|
|
||||
template <class T> |
|
||||
struct portable_rebind_alloc |
|
||||
{ typedef typename boost::intrusive::pointer_rebind<Allocator, T>::type type; }; |
|
||||
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//! <b>Returns</b>: <code>a.allocate(n)</code>
|
|
||||
//!
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n) |
|
||||
{ return a.allocate(n); } |
|
||||
|
|
||||
//! <b>Returns</b>: <code>a.deallocate(p, n)</code>
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing
|
|
||||
BOOST_CONTAINER_FORCEINLINE static void deallocate(Allocator &a, pointer p, size_type n) |
|
||||
{ a.deallocate(p, n); } |
|
||||
|
|
||||
//! <b>Effects</b>: calls <code>a.allocate(n, p)</code> if that call is well-formed;
|
|
||||
//! otherwise, invokes <code>a.allocate(n)</code>
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n, const_void_pointer p) |
|
||||
{ |
|
||||
const bool value = boost::container::dtl:: |
|
||||
has_member_function_callable_with_allocate |
|
||||
<Allocator, const size_type, const const_void_pointer>::value; |
|
||||
dtl::bool_<value> flag; |
|
||||
return allocator_traits::priv_allocate(flag, a, n, p); |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: calls <code>a.destroy(p)</code> if that call is well-formed;
|
|
||||
//! otherwise, invokes <code>p->~T()</code>.
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
typedef T* destroy_pointer; |
|
||||
const bool value = boost::container::dtl:: |
|
||||
has_member_function_callable_with_destroy |
|
||||
<Allocator, const destroy_pointer>::value; |
|
||||
dtl::bool_<value> flag; |
|
||||
allocator_traits::priv_destroy(flag, a, p); |
|
||||
} |
|
||||
|
|
||||
//! <b>Returns</b>: <code>a.max_size()</code> if that expression is well-formed; otherwise,
|
|
||||
//! <code>numeric_limits<size_type>::max()</code>.
|
|
||||
BOOST_CONTAINER_FORCEINLINE static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
const bool value = allocator_traits_detail::has_max_size<Allocator, size_type (Allocator::*)() const>::value; |
|
||||
dtl::bool_<value> flag; |
|
||||
return allocator_traits::priv_max_size(flag, a); |
|
||||
} |
|
||||
|
|
||||
//! <b>Returns</b>: <code>a.select_on_container_copy_construction()</code> if that expression is well-formed;
|
|
||||
//! otherwise, a.
|
|
||||
BOOST_CONTAINER_FORCEINLINE static BOOST_CONTAINER_DOC1ST(Allocator, |
|
||||
typename dtl::if_c |
|
||||
< allocator_traits_detail::has_select_on_container_copy_construction<Allocator BOOST_MOVE_I Allocator (Allocator::*)() const>::value |
|
||||
BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type) |
|
||||
select_on_container_copy_construction(const Allocator &a) |
|
||||
{ |
|
||||
const bool value = allocator_traits_detail::has_select_on_container_copy_construction |
|
||||
<Allocator, Allocator (Allocator::*)() const>::value; |
|
||||
dtl::bool_<value> flag; |
|
||||
return allocator_traits::priv_select_on_container_copy_construction(flag, a); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
//! <b>Effects</b>: calls <code>a.construct(p, std::forward<Args>(args)...)</code> if that call is well-formed;
|
|
||||
//! otherwise, invokes <code>`placement new` (static_cast<void*>(p)) T(std::forward<Args>(args)...)</code>
|
|
||||
template <class T, class ...Args> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) |
|
||||
{ |
|
||||
static const bool value = ::boost::move_detail::and_ |
|
||||
< dtl::is_not_std_allocator<Allocator> |
|
||||
, boost::container::dtl::has_member_function_callable_with_construct |
|
||||
< Allocator, T*, Args... > |
|
||||
>::value; |
|
||||
dtl::bool_<value> flag; |
|
||||
allocator_traits::priv_construct(flag, a, p, ::boost::forward<Args>(args)...); |
|
||||
} |
|
||||
#endif
|
|
||||
|
|
||||
//! <b>Returns</b>: <code>a.storage_is_unpropagable(p)</code> if is_partially_propagable::value is true; otherwise,
|
|
||||
//! <code>false</code>.
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
dtl::bool_<is_partially_propagable::value> flag; |
|
||||
return allocator_traits::priv_storage_is_unpropagable(flag, a, p); |
|
||||
} |
|
||||
|
|
||||
//! <b>Returns</b>: <code>true</code> if <code>is_always_equal::value == true</code>, otherwise,
|
|
||||
//! <code>a == b</code>.
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
dtl::bool_<is_always_equal::value> flag; |
|
||||
return allocator_traits::priv_equal(flag, a, b); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
private: |
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::true_type, Allocator &a, size_type n, const_void_pointer p) |
|
||||
{ return a.allocate(n, p); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::false_type, Allocator &a, size_type n, const_void_pointer) |
|
||||
{ return a.allocate(n); } |
|
||||
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ a.destroy(p); } |
|
||||
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ p->~T(); (void)p; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return a.max_size(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return size_type(-1)/sizeof(value_type); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static Allocator priv_select_on_container_copy_construction(dtl::true_type, const Allocator &a) |
|
||||
{ return a.select_on_container_copy_construction(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static const Allocator &priv_select_on_container_copy_construction(dtl::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return a; } |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
template<class T, class ...Args> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) |
|
||||
{ a.construct( p, ::boost::forward<Args>(args)...); } |
|
||||
|
|
||||
template<class T, class ...Args> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) |
|
||||
{ ::new((void*)p, boost_container_new_t()) T(::boost::forward<Args>(args)...); } |
|
||||
#else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
public: |
|
||||
|
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \
|
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ |
|
||||
BOOST_CONTAINER_FORCEINLINE static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ |
|
||||
{\ |
|
||||
static const bool value = ::boost::move_detail::and_ \ |
|
||||
< dtl::is_not_std_allocator<Allocator> \ |
|
||||
, boost::container::dtl::has_member_function_callable_with_construct \ |
|
||||
< Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \ |
|
||||
>::value; \ |
|
||||
dtl::bool_<value> flag;\ |
|
||||
(priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) |
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL
|
|
||||
|
|
||||
private: |
|
||||
/////////////////////////////////
|
|
||||
// priv_construct
|
|
||||
/////////////////////////////////
|
|
||||
#define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \
|
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ |
|
||||
{ a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ |
|
||||
\ |
|
||||
template<class T BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ |
|
||||
{ ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) |
|
||||
#undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL
|
|
||||
|
|
||||
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) |
|
||||
{ ::new((void*)p, boost_container_new_t()) T; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::true_type, const Allocator &a, pointer p) |
|
||||
{ return a.storage_is_unpropagable(p); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::false_type, const Allocator &, pointer) |
|
||||
{ return false; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::true_type, const Allocator &, const Allocator &) |
|
||||
{ return true; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::false_type, const Allocator &a, const Allocator &b) |
|
||||
{ return a == b; } |
|
||||
|
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<class T, class AllocatorOrVoid> |
|
||||
struct real_allocator |
|
||||
{ |
|
||||
typedef AllocatorOrVoid type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct real_allocator<T, void> |
|
||||
{ |
|
||||
typedef new_allocator<T> type; |
|
||||
}; |
|
||||
|
|
||||
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP)
|
|
@ -1,388 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2014. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
|
|
||||
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//! \file
|
|
||||
//! This header file forward declares the following containers:
|
|
||||
//! - boost::container::vector
|
|
||||
//! - boost::container::stable_vector
|
|
||||
//! - boost::container::static_vector
|
|
||||
//! - boost::container::small_vector_base
|
|
||||
//! - boost::container::small_vector
|
|
||||
//! - boost::container::devector
|
|
||||
//! - boost::container::slist
|
|
||||
//! - boost::container::list
|
|
||||
//! - boost::container::set
|
|
||||
//! - boost::container::multiset
|
|
||||
//! - boost::container::map
|
|
||||
//! - boost::container::multimap
|
|
||||
//! - boost::container::flat_set
|
|
||||
//! - boost::container::flat_multiset
|
|
||||
//! - boost::container::flat_map
|
|
||||
//! - boost::container::flat_multimap
|
|
||||
//! - boost::container::basic_string
|
|
||||
//! - boost::container::string
|
|
||||
//! - boost::container::wstring
|
|
||||
//!
|
|
||||
//! Forward declares the following allocators:
|
|
||||
//! - boost::container::allocator
|
|
||||
//! - boost::container::node_allocator
|
|
||||
//! - boost::container::adaptive_pool
|
|
||||
//!
|
|
||||
//! Forward declares the following polymorphic resource classes:
|
|
||||
//! - boost::container::pmr::memory_resource
|
|
||||
//! - boost::container::pmr::polymorphic_allocator
|
|
||||
//! - boost::container::pmr::monotonic_buffer_resource
|
|
||||
//! - boost::container::pmr::pool_options
|
|
||||
//! - boost::container::pmr::unsynchronized_pool_resource
|
|
||||
//! - boost::container::pmr::synchronized_pool_resource
|
|
||||
//!
|
|
||||
//! And finally it defines the following types
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//Std forward declarations
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace intrusive{ |
|
||||
namespace detail{ |
|
||||
//Create namespace to avoid compilation errors
|
|
||||
}}} |
|
||||
|
|
||||
namespace boost{ namespace container{ namespace dtl{ |
|
||||
namespace bi = boost::intrusive; |
|
||||
namespace bid = boost::intrusive::detail; |
|
||||
}}} |
|
||||
|
|
||||
namespace boost{ namespace container{ namespace pmr{ |
|
||||
namespace bi = boost::intrusive; |
|
||||
namespace bid = boost::intrusive::detail; |
|
||||
}}} |
|
||||
|
|
||||
#include <cstddef>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
// Containers
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
template<class T> |
|
||||
class new_allocator; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void |
|
||||
,class Options = void> |
|
||||
class vector; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void > |
|
||||
class stable_vector; |
|
||||
|
|
||||
template < class T |
|
||||
, std::size_t Capacity |
|
||||
, class Options = void> |
|
||||
class static_vector; |
|
||||
|
|
||||
template < class T |
|
||||
, class Allocator = void |
|
||||
, class Options = void > |
|
||||
class small_vector_base; |
|
||||
|
|
||||
template < class T |
|
||||
, std::size_t N |
|
||||
, class Allocator = void |
|
||||
, class Options = void > |
|
||||
class small_vector; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void |
|
||||
,class Options = void> |
|
||||
class devector; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void |
|
||||
,class Options = void> |
|
||||
class deque; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void > |
|
||||
class list; |
|
||||
|
|
||||
template <class T |
|
||||
,class Allocator = void > |
|
||||
class slist; |
|
||||
|
|
||||
template <class Key |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void |
|
||||
,class Options = void> |
|
||||
class set; |
|
||||
|
|
||||
template <class Key |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void |
|
||||
,class Options = void > |
|
||||
class multiset; |
|
||||
|
|
||||
template <class Key |
|
||||
,class T |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void |
|
||||
,class Options = void > |
|
||||
class map; |
|
||||
|
|
||||
template <class Key |
|
||||
,class T |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void |
|
||||
,class Options = void > |
|
||||
class multimap; |
|
||||
|
|
||||
template <class Key |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void > |
|
||||
class flat_set; |
|
||||
|
|
||||
template <class Key |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void > |
|
||||
class flat_multiset; |
|
||||
|
|
||||
template <class Key |
|
||||
,class T |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void > |
|
||||
class flat_map; |
|
||||
|
|
||||
template <class Key |
|
||||
,class T |
|
||||
,class Compare = std::less<Key> |
|
||||
,class Allocator = void > |
|
||||
class flat_multimap; |
|
||||
|
|
||||
#ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
|
|
||||
|
|
||||
//! Alias templates for small_flat_[multi]{set|map} using small_vector as container
|
|
||||
|
|
||||
template < class Key |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
using small_flat_set = flat_set<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions>>; |
|
||||
|
|
||||
template < class Key |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
using small_flat_multiset = flat_multiset<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions>>; |
|
||||
|
|
||||
template < class Key |
|
||||
, class T |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
using small_flat_map = flat_map<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions>>; |
|
||||
|
|
||||
template < class Key |
|
||||
, class T |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
using small_flat_multimap = flat_multimap<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions>>; |
|
||||
|
|
||||
#endif // #ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES
|
|
||||
|
|
||||
|
|
||||
//! A portable metafunction to obtain a small_flat_set
|
|
||||
template < class Key |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
struct small_flat_set_of |
|
||||
{ |
|
||||
typedef flat_set<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type; |
|
||||
}; |
|
||||
|
|
||||
//! A portable metafunction to obtain a small_flat_multiset
|
|
||||
template < class Key |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
struct small_flat_multiset_of |
|
||||
{ |
|
||||
typedef flat_multiset<Key, Compare, small_vector<Key, N, SmallVectorAllocator, SmallVectorOptions> > type; |
|
||||
}; |
|
||||
|
|
||||
//! A portable metafunction to obtain a small_flat_map
|
|
||||
template < class Key |
|
||||
, class T |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
struct small_flat_map_of |
|
||||
{ |
|
||||
typedef flat_map<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type; |
|
||||
}; |
|
||||
|
|
||||
//! A portable metafunction to obtain a small_flat_multimap
|
|
||||
template < class Key |
|
||||
, class T |
|
||||
, std::size_t N |
|
||||
, class Compare = std::less<Key> |
|
||||
, class SmallVectorAllocator = void |
|
||||
, class SmallVectorOptions = void > |
|
||||
struct small_flat_multimap_of |
|
||||
{ |
|
||||
typedef flat_multimap<Key, T, Compare, small_vector<std::pair<Key, T>, N, SmallVectorAllocator, SmallVectorOptions> > type; |
|
||||
}; |
|
||||
|
|
||||
template <class CharT |
|
||||
,class Traits = std::char_traits<CharT> |
|
||||
,class Allocator = void > |
|
||||
class basic_string; |
|
||||
|
|
||||
typedef basic_string <char> string; |
|
||||
typedef basic_string<wchar_t> wstring; |
|
||||
|
|
||||
static const std::size_t ADP_nodes_per_block = 256u; |
|
||||
static const std::size_t ADP_max_free_blocks = 2u; |
|
||||
static const std::size_t ADP_overhead_percent = 1u; |
|
||||
static const std::size_t ADP_only_alignment = 0u; |
|
||||
|
|
||||
template < class T |
|
||||
, std::size_t NodesPerBlock = ADP_nodes_per_block |
|
||||
, std::size_t MaxFreeBlocks = ADP_max_free_blocks |
|
||||
, std::size_t OverheadPercent = ADP_overhead_percent |
|
||||
, unsigned Version = 2 |
|
||||
> |
|
||||
class adaptive_pool; |
|
||||
|
|
||||
template < class T |
|
||||
, unsigned Version = 2 |
|
||||
, unsigned int AllocationDisableMask = 0> |
|
||||
class allocator; |
|
||||
|
|
||||
static const std::size_t NodeAlloc_nodes_per_block = 256u; |
|
||||
|
|
||||
template |
|
||||
< class T |
|
||||
, std::size_t NodesPerBlock = NodeAlloc_nodes_per_block |
|
||||
, std::size_t Version = 2> |
|
||||
class node_allocator; |
|
||||
|
|
||||
namespace pmr { |
|
||||
|
|
||||
class memory_resource; |
|
||||
|
|
||||
template<class T> |
|
||||
class polymorphic_allocator; |
|
||||
|
|
||||
class monotonic_buffer_resource; |
|
||||
|
|
||||
struct pool_options; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
class resource_adaptor_imp; |
|
||||
|
|
||||
class unsynchronized_pool_resource; |
|
||||
|
|
||||
class synchronized_pool_resource; |
|
||||
|
|
||||
} //namespace pmr {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//! Type used to tag that the input range is
|
|
||||
//! guaranteed to be ordered
|
|
||||
struct ordered_range_t |
|
||||
{}; |
|
||||
|
|
||||
//! Value used to tag that the input range is
|
|
||||
//! guaranteed to be ordered
|
|
||||
static const ordered_range_t ordered_range = ordered_range_t(); |
|
||||
|
|
||||
//! Type used to tag that the input range is
|
|
||||
//! guaranteed to be ordered and unique
|
|
||||
struct ordered_unique_range_t |
|
||||
: public ordered_range_t |
|
||||
{}; |
|
||||
|
|
||||
//! Value used to tag that the input range is
|
|
||||
//! guaranteed to be ordered and unique
|
|
||||
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); |
|
||||
|
|
||||
//! Type used to tag that the inserted values
|
|
||||
//! should be default initialized
|
|
||||
struct default_init_t |
|
||||
{}; |
|
||||
|
|
||||
//! Value used to tag that the inserted values
|
|
||||
//! should be default initialized
|
|
||||
static const default_init_t default_init = default_init_t(); |
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//! Type used to tag that the inserted values
|
|
||||
//! should be value initialized
|
|
||||
struct value_init_t |
|
||||
{}; |
|
||||
|
|
||||
//! Value used to tag that the inserted values
|
|
||||
//! should be value initialized
|
|
||||
static const value_init_t value_init = value_init_t(); |
|
||||
|
|
||||
namespace container_detail_really_deep_namespace { |
|
||||
|
|
||||
//Otherwise, gcc issues a warning of previously defined
|
|
||||
//anonymous_instance and unique_instance
|
|
||||
struct dummy |
|
||||
{ |
|
||||
dummy() |
|
||||
{ |
|
||||
(void)ordered_range; |
|
||||
(void)ordered_unique_range; |
|
||||
(void)default_init; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} //detail_really_deep_namespace {
|
|
||||
|
|
||||
typedef const std::piecewise_construct_t & piecewise_construct_t; |
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
}} //namespace boost { namespace container {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
|
|
@ -1,33 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/move/detail/addressof.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
using boost::move_detail::addressof; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP
|
|
@ -1,542 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
// container
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
// container/detail
|
|
||||
#include <boost/container/detail/copy_move_algo.hpp>
|
|
||||
#include <boost/container/detail/destroyers.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/iterator.hpp>
|
|
||||
#include <boost/container/detail/iterators.hpp>
|
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
|
||||
#endif
|
|
||||
// move
|
|
||||
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/move/detail/force_ptr.hpp>
|
|
||||
// other
|
|
||||
#include <boost/assert.hpp>
|
|
||||
|
|
||||
namespace boost { namespace container { namespace dtl { |
|
||||
|
|
||||
template<class Allocator, class FwdIt> |
|
||||
struct move_insert_range_proxy |
|
||||
{ |
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first) |
|
||||
: first_(first) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
this->first_ = ::boost::container::uninitialized_move_alloc_n_source |
|
||||
(a, this->first_, n, p); |
|
||||
} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
this->first_ = ::boost::container::move_n_source(this->first_, n, p); |
|
||||
} |
|
||||
|
|
||||
FwdIt first_; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class Allocator, class FwdIt> |
|
||||
struct insert_range_proxy |
|
||||
{ |
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first) |
|
||||
: first_(first) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); |
|
||||
} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
this->first_ = ::boost::container::copy_n_source(this->first_, n, p); |
|
||||
} |
|
||||
|
|
||||
FwdIt first_; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_n_copies_proxy |
|
||||
{ |
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v) |
|
||||
: v_(v) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
while (n){ |
|
||||
--n; |
|
||||
*p = v_; |
|
||||
++p; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
const value_type &v_; |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_value_initialized_n_proxy |
|
||||
{ |
|
||||
typedef ::boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type; |
|
||||
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ boost::container::uninitialized_value_init_alloc_n(a, n, p); } |
|
||||
|
|
||||
template<class Iterator> |
|
||||
void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
while (n){ |
|
||||
--n; |
|
||||
storage_t v; |
|
||||
alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v)); |
|
||||
value_type *vp = move_detail::force_ptr<value_type *>(&v); |
|
||||
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; |
|
||||
*p = ::boost::move(*vp); |
|
||||
++p; |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_default_initialized_n_proxy |
|
||||
{ |
|
||||
typedef ::boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename allocator_traits<Allocator>::value_type value_type; |
|
||||
typedef typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type storage_t; |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ boost::container::uninitialized_default_init_alloc_n(a, n, p); } |
|
||||
|
|
||||
template<class Iterator> |
|
||||
void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
if(!is_pod<value_type>::value){ |
|
||||
while (n){ |
|
||||
--n; |
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; |
|
||||
alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), default_init); |
|
||||
value_type *vp = move_detail::force_ptr<value_type *>(&v); |
|
||||
value_destructor<Allocator> on_exit(a, *vp); (void)on_exit; |
|
||||
*p = ::boost::move(*vp); |
|
||||
++p; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_copy_proxy |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename alloc_traits::value_type value_type; |
|
||||
|
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v) |
|
||||
: v_(v) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
BOOST_ASSERT(n == 1); (void)n; |
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); |
|
||||
} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
BOOST_ASSERT(n == 1); (void)n; |
|
||||
*p = v_; |
|
||||
} |
|
||||
|
|
||||
const value_type &v_; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_move_proxy |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename alloc_traits::value_type value_type; |
|
||||
|
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v) |
|
||||
: v_(v) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
BOOST_ASSERT(n == 1); (void)n; |
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); |
|
||||
} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, std::size_t n) const |
|
||||
{ |
|
||||
BOOST_ASSERT(n == 1); (void)n; |
|
||||
*p = ::boost::move(v_); |
|
||||
} |
|
||||
|
|
||||
value_type &v_; |
|
||||
}; |
|
||||
|
|
||||
template<class It, class Allocator> |
|
||||
BOOST_CONTAINER_FORCEINLINE insert_move_proxy<Allocator> get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits<It>::value_type) v) |
|
||||
{ |
|
||||
return insert_move_proxy<Allocator>(v); |
|
||||
} |
|
||||
|
|
||||
template<class It, class Allocator> |
|
||||
BOOST_CONTAINER_FORCEINLINE insert_copy_proxy<Allocator> get_insert_value_proxy(const typename boost::container::iterator_traits<It>::value_type &v) |
|
||||
{ |
|
||||
return insert_copy_proxy<Allocator>(v); |
|
||||
} |
|
||||
|
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class Allocator, class ...Args> |
|
||||
struct insert_nonmovable_emplace_proxy |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename alloc_traits::value_type value_type; |
|
||||
typedef typename build_number_seq<sizeof...(Args)>::type index_tuple_t; |
|
||||
|
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) |
|
||||
: args_(args...) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
|
||||
{ this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } |
|
||||
|
|
||||
private: |
|
||||
template<std::size_t ...IdxPack, class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
BOOST_ASSERT(n == 1); (void)n; |
|
||||
alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward<Args>(get<IdxPack>(this->args_))... ); |
|
||||
} |
|
||||
|
|
||||
protected: |
|
||||
tuple<Args&...> args_; |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator, class ...Args> |
|
||||
struct insert_emplace_proxy |
|
||||
: public insert_nonmovable_emplace_proxy<Allocator, Args...> |
|
||||
{ |
|
||||
typedef insert_nonmovable_emplace_proxy<Allocator, Args...> base_t; |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits; |
|
||||
typedef typename base_t::value_type value_type; |
|
||||
typedef typename base_t::index_tuple_t index_tuple_t; |
|
||||
|
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) |
|
||||
: base_t(::boost::forward<Args>(args)...) |
|
||||
{} |
|
||||
|
|
||||
template<class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n) |
|
||||
{ this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
template<std::size_t ...IdxPack, class Iterator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple<IdxPack...>&, Iterator p, std::size_t n) |
|
||||
{ |
|
||||
BOOST_ASSERT(n ==1); (void)n; |
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v; |
|
||||
alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v), ::boost::forward<Args>(get<IdxPack>(this->args_))...); |
|
||||
value_type *vp = move_detail::force_ptr<value_type *>(&v); |
|
||||
BOOST_CONTAINER_TRY{ |
|
||||
*p = ::boost::move(*vp); |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH(...){ |
|
||||
alloc_traits::destroy(a, vp); |
|
||||
BOOST_CONTAINER_RETHROW |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH_END |
|
||||
alloc_traits::destroy(a, vp); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy<Allocator, typename boost::container::allocator_traits<Allocator>::value_type> |
|
||||
: public insert_move_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits<Allocator>::value_type &&v) |
|
||||
: insert_move_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking
|
|
||||
//compiler error C2752 ("more than one partial specialization matches").
|
|
||||
//Any problem is solvable with an extra layer of indirection? ;-)
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy<Allocator |
|
||||
, typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type |
|
||||
> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
|
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy<Allocator, typename boost::container::allocator_traits<Allocator>::value_type &> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy<Allocator |
|
||||
, typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type & |
|
||||
> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
|
||||
|
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
#include <boost/container/detail/value_init.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \
|
|
||||
template< class Allocator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ |
|
||||
struct insert_nonmovable_emplace_proxy##N\ |
|
||||
{\ |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;\ |
|
||||
typedef typename alloc_traits::value_type value_type;\ |
|
||||
\ |
|
||||
static const bool single_value = true;\ |
|
||||
\ |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ |
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ |
|
||||
\ |
|
||||
template<class Iterator>\ |
|
||||
BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ |
|
||||
{\ |
|
||||
BOOST_ASSERT(n == 1); (void)n;\ |
|
||||
alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ |
|
||||
}\ |
|
||||
\ |
|
||||
template<class Iterator>\ |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, std::size_t)\ |
|
||||
{ BOOST_ASSERT(false); }\ |
|
||||
\ |
|
||||
protected:\ |
|
||||
BOOST_MOVE_MREF##N\ |
|
||||
};\ |
|
||||
\ |
|
||||
template< class Allocator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ |
|
||||
struct insert_emplace_proxy_arg##N\ |
|
||||
: insert_nonmovable_emplace_proxy##N< Allocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\ |
|
||||
{\ |
|
||||
typedef insert_nonmovable_emplace_proxy##N\ |
|
||||
< Allocator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ |
|
||||
typedef typename base_t::value_type value_type;\ |
|
||||
typedef boost::container::allocator_traits<Allocator> alloc_traits;\ |
|
||||
\ |
|
||||
static const bool single_value = true;\ |
|
||||
\ |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ |
|
||||
: base_t(BOOST_MOVE_FWD##N){}\ |
|
||||
\ |
|
||||
template<class Iterator>\ |
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, std::size_t n)\ |
|
||||
{\ |
|
||||
BOOST_ASSERT(n == 1); (void)n;\ |
|
||||
typename dtl::aligned_storage<sizeof(value_type), dtl::alignment_of<value_type>::value>::type v;\ |
|
||||
alloc_traits::construct(a, move_detail::force_ptr<value_type *>(&v) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ |
|
||||
value_type *vp = move_detail::force_ptr<value_type *>(&v);\ |
|
||||
BOOST_CONTAINER_TRY{\ |
|
||||
*p = ::boost::move(*vp);\ |
|
||||
}\ |
|
||||
BOOST_CONTAINER_CATCH(...){\ |
|
||||
alloc_traits::destroy(a, vp);\ |
|
||||
BOOST_CONTAINER_RETHROW\ |
|
||||
}\ |
|
||||
BOOST_CONTAINER_CATCH_END\ |
|
||||
alloc_traits::destroy(a, vp);\ |
|
||||
}\ |
|
||||
};\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE) |
|
||||
#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE
|
|
||||
|
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
|
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator, ::boost::rv<typename boost::container::allocator_traits<Allocator>::value_type> > |
|
||||
: public insert_move_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_move_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
#else //e.g. MSVC10 & MSVC11
|
|
||||
|
|
||||
//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type> |
|
||||
: public insert_move_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits<Allocator>::value_type &&v) |
|
||||
: insert_move_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking
|
|
||||
//compiler error C2752 ("more than one partial specialization matches").
|
|
||||
//Any problem is solvable with an extra layer of indirection? ;-)
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator |
|
||||
, typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type |
|
||||
> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator, typename boost::container::allocator_traits<Allocator>::value_type &> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct insert_emplace_proxy_arg1<Allocator |
|
||||
, typename boost::container::dtl::add_const<typename boost::container::allocator_traits<Allocator>::value_type>::type & |
|
||||
> |
|
||||
: public insert_copy_proxy<Allocator> |
|
||||
{ |
|
||||
static const bool single_value = true; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits<Allocator>::value_type &v) |
|
||||
: insert_copy_proxy<Allocator>(v) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
|
||||
|
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP
|
|
@ -1,185 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/intrusive/detail/algorithm.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
using boost::intrusive::algo_equal; |
|
||||
using boost::intrusive::algo_lexicographical_compare; |
|
||||
|
|
||||
template<class Func> |
|
||||
class binder1st |
|
||||
{ |
|
||||
public: |
|
||||
typedef typename Func::second_argument_type argument_type; |
|
||||
typedef typename Func::result_type result_type; |
|
||||
|
|
||||
binder1st(const Func& func, const typename Func::first_argument_type& arg) |
|
||||
: op(func), value(arg) |
|
||||
{} |
|
||||
|
|
||||
result_type operator()(const argument_type& arg) const |
|
||||
{ return op(value, arg); } |
|
||||
|
|
||||
result_type operator()(argument_type& arg) const |
|
||||
{ return op(value, arg); } |
|
||||
|
|
||||
private: |
|
||||
Func op; |
|
||||
typename Func::first_argument_type value; |
|
||||
}; |
|
||||
|
|
||||
template<class Func, class T> |
|
||||
inline binder1st<Func> bind1st(const Func& func, const T& arg) |
|
||||
{ return boost::container::binder1st<Func>(func, arg); } |
|
||||
|
|
||||
template<class Func> |
|
||||
class binder2nd |
|
||||
{ |
|
||||
public: |
|
||||
typedef typename Func::first_argument_type argument_type; |
|
||||
typedef typename Func::result_type result_type; |
|
||||
|
|
||||
binder2nd(const Func& func, const typename Func::second_argument_type& arg) |
|
||||
: op(func), value(arg) |
|
||||
{} |
|
||||
|
|
||||
result_type operator()(const argument_type& arg) const |
|
||||
{ return op(arg, value); } |
|
||||
|
|
||||
result_type operator()(argument_type& arg) const |
|
||||
{ return op(arg, value); } |
|
||||
|
|
||||
private: |
|
||||
Func op; |
|
||||
typename Func::second_argument_type value; |
|
||||
}; |
|
||||
|
|
||||
template<class Func, class T> |
|
||||
inline binder2nd<Func> bind2nd(const Func& func, const T& arg) |
|
||||
{ |
|
||||
return (boost::container::binder2nd<Func>(func, arg)); |
|
||||
} |
|
||||
|
|
||||
template<class Func> |
|
||||
class unary_negate |
|
||||
{ |
|
||||
public: |
|
||||
typedef typename Func::argument_type argument_type; |
|
||||
typedef typename Func::result_type result_type; |
|
||||
|
|
||||
explicit unary_negate(const Func& func) |
|
||||
: m_func(func) |
|
||||
{} |
|
||||
|
|
||||
bool operator()(const typename Func::argument_type& arg) const |
|
||||
{ return !m_func(arg); } |
|
||||
|
|
||||
private: |
|
||||
Func m_func; |
|
||||
}; |
|
||||
|
|
||||
template<class Func> inline |
|
||||
unary_negate<Func> not1(const Func& func) |
|
||||
{ |
|
||||
return boost::container::unary_negate<Func>(func); |
|
||||
} |
|
||||
|
|
||||
template<class InputIt, class UnaryPredicate> |
|
||||
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) |
|
||||
{ |
|
||||
for (; first != last; ++first) { |
|
||||
if (p(*first)) { |
|
||||
return first; |
|
||||
} |
|
||||
} |
|
||||
return last; |
|
||||
} |
|
||||
|
|
||||
template<class ForwardIt1, class ForwardIt2, class BinaryPredicate> |
|
||||
ForwardIt1 find_end (ForwardIt1 first1, ForwardIt1 last1 |
|
||||
,ForwardIt2 first2, ForwardIt2 last2 |
|
||||
,BinaryPredicate p) |
|
||||
{ |
|
||||
if (first2==last2) |
|
||||
return last1; // specified in C++11
|
|
||||
|
|
||||
ForwardIt1 ret = last1; |
|
||||
|
|
||||
while (first1!=last1) |
|
||||
{ |
|
||||
ForwardIt1 it1 = first1; |
|
||||
ForwardIt2 it2 = first2; |
|
||||
while ( p(*it1, *it2) ) { |
|
||||
++it1; ++it2; |
|
||||
if (it2==last2) { |
|
||||
ret=first1; |
|
||||
break; |
|
||||
} |
|
||||
if (it1==last1) |
|
||||
return ret; |
|
||||
} |
|
||||
++first1; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
template<class InputIt, class ForwardIt, class BinaryPredicate> |
|
||||
InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p) |
|
||||
{ |
|
||||
for (; first1 != last1; ++first1) { |
|
||||
for (ForwardIt it = first2; it != last2; ++it) { |
|
||||
if (p(*first1, *it)) { |
|
||||
return first1; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return last1; |
|
||||
} |
|
||||
|
|
||||
template<class ForwardIt1, class ForwardIt2, class BinaryPredicate> |
|
||||
ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1, |
|
||||
ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p) |
|
||||
{ |
|
||||
for (; ; ++first1) { |
|
||||
ForwardIt1 it = first1; |
|
||||
for (ForwardIt2 it2 = first2; ; ++it, ++it2) { |
|
||||
if (it2 == last2) { |
|
||||
return first1; |
|
||||
} |
|
||||
if (it == last1) { |
|
||||
return last1; |
|
||||
} |
|
||||
if (!p(*it, *it2)) { |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP
|
|
@ -1,60 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
// move
|
|
||||
#include <boost/move/adl_move_swap.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type) |
|
||||
BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) |
|
||||
{ boost::adl_move_swap(l, r); } |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type) |
|
||||
BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type) |
|
||||
{ l = r; } |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type) |
|
||||
BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
template<class AllocatorType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) |
|
||||
{ l = ::boost::move(r); } |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP
|
|
@ -1,58 +0,0 @@ |
|||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
|
||||
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
enum allocation_type_v |
|
||||
{ |
|
||||
// constants for allocation commands
|
|
||||
allocate_new_v = 0x01, |
|
||||
expand_fwd_v = 0x02, |
|
||||
expand_bwd_v = 0x04, |
|
||||
// expand_both = expand_fwd | expand_bwd,
|
|
||||
// expand_or_new = allocate_new | expand_both,
|
|
||||
shrink_in_place_v = 0x08, |
|
||||
nothrow_allocation_v = 0x10, |
|
||||
zero_memory_v = 0x20, |
|
||||
try_shrink_in_place_v = 0x40 |
|
||||
}; |
|
||||
|
|
||||
typedef unsigned int allocation_type; |
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
static const allocation_type allocate_new = (allocation_type)allocate_new_v; |
|
||||
static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; |
|
||||
static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; |
|
||||
static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v; |
|
||||
static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v; |
|
||||
static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v; |
|
||||
static const allocation_type zero_memory = (allocation_type)zero_memory_v; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP
|
|
@ -1,162 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/container/allocator_traits.hpp> //allocator_traits
|
|
||||
#include <boost/container/throw_exception.hpp>
|
|
||||
#include <boost/container/detail/multiallocation_chain.hpp> //multiallocation_chain
|
|
||||
#include <boost/container/detail/version_type.hpp> //version_type
|
|
||||
#include <boost/container/detail/allocation_type.hpp> //allocation_type
|
|
||||
#include <boost/container/detail/mpl.hpp> //integral_constant
|
|
||||
#include <boost/intrusive/pointer_traits.hpp> //pointer_traits
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class Allocator, unsigned Version = boost::container::dtl::version<Allocator>::value> |
|
||||
struct allocator_version_traits |
|
||||
{ |
|
||||
typedef ::boost::container::dtl::integral_constant |
|
||||
<unsigned, Version> alloc_version; |
|
||||
|
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain; |
|
||||
|
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; |
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; |
|
||||
|
|
||||
//Node allocation interface
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer allocate_one(Allocator &a) |
|
||||
{ return a.allocate_one(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static void deallocate_one(Allocator &a, const pointer &p) |
|
||||
{ a.deallocate_one(p); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) |
|
||||
{ return a.allocate_individual(n, m); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static void deallocate_individual(Allocator &a, multiallocation_chain &holder) |
|
||||
{ a.deallocate_individual(holder); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer allocation_command(Allocator &a, allocation_type command, |
|
||||
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) |
|
||||
{ return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); } |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
struct allocator_version_traits<Allocator, 1> |
|
||||
{ |
|
||||
typedef ::boost::container::dtl::integral_constant |
|
||||
<unsigned, 1> alloc_version; |
|
||||
|
|
||||
typedef typename boost::container::allocator_traits<Allocator>::pointer pointer; |
|
||||
typedef typename boost::container::allocator_traits<Allocator>::size_type size_type; |
|
||||
typedef typename boost::container::allocator_traits<Allocator>::value_type value_type; |
|
||||
|
|
||||
typedef typename boost::intrusive::pointer_traits<pointer>:: |
|
||||
template rebind_pointer<void>::type void_ptr; |
|
||||
typedef dtl::basic_multiallocation_chain |
|
||||
<void_ptr> multialloc_cached_counted; |
|
||||
typedef boost::container::dtl:: |
|
||||
transform_multiallocation_chain |
|
||||
< multialloc_cached_counted, value_type> multiallocation_chain; |
|
||||
|
|
||||
//Node allocation interface
|
|
||||
BOOST_CONTAINER_FORCEINLINE static pointer allocate_one(Allocator &a) |
|
||||
{ return a.allocate(1); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static void deallocate_one(Allocator &a, const pointer &p) |
|
||||
{ a.deallocate(p, 1); } |
|
||||
|
|
||||
static void deallocate_individual(Allocator &a, multiallocation_chain &holder) |
|
||||
{ |
|
||||
size_type n = holder.size(); |
|
||||
typename multiallocation_chain::iterator it = holder.begin(); |
|
||||
while(n){ |
|
||||
--n; |
|
||||
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it); |
|
||||
++it; |
|
||||
a.deallocate(p, 1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
struct allocate_individual_rollback |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE allocate_individual_rollback(Allocator &a, multiallocation_chain &chain) |
|
||||
: mr_a(a), mp_chain(&chain) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~allocate_individual_rollback() |
|
||||
{ |
|
||||
if(mp_chain) |
|
||||
allocator_version_traits::deallocate_individual(mr_a, *mp_chain); |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{ |
|
||||
mp_chain = 0; |
|
||||
} |
|
||||
|
|
||||
Allocator &mr_a; |
|
||||
multiallocation_chain * mp_chain; |
|
||||
}; |
|
||||
|
|
||||
static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) |
|
||||
{ |
|
||||
allocate_individual_rollback rollback(a, m); |
|
||||
while(n--){ |
|
||||
m.push_front(a.allocate(1)); |
|
||||
} |
|
||||
rollback.release(); |
|
||||
} |
|
||||
|
|
||||
static pointer allocation_command(Allocator &a, allocation_type command, |
|
||||
size_type, size_type &prefer_in_recvd_out_size, pointer &reuse) |
|
||||
{ |
|
||||
pointer ret = pointer(); |
|
||||
if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){ |
|
||||
throw_logic_error("version 1 allocator without allocate_new flag"); |
|
||||
} |
|
||||
else{ |
|
||||
BOOST_CONTAINER_TRY{ |
|
||||
ret = a.allocate(prefer_in_recvd_out_size); |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH(...){ |
|
||||
if(!(command & nothrow_allocation)){ |
|
||||
BOOST_CONTAINER_RETHROW |
|
||||
} |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH_END |
|
||||
reuse = pointer(); |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP)
|
|
@ -1,134 +0,0 @@ |
|||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
template<class ValueType> |
|
||||
class equal_to_value |
|
||||
{ |
|
||||
typedef ValueType value_type; |
|
||||
const value_type &t_; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit equal_to_value(const value_type &t) |
|
||||
: t_(t) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const value_type &t)const |
|
||||
{ return t_ == t; } |
|
||||
}; |
|
||||
|
|
||||
template<class Node, class Pred, class Ret = bool> |
|
||||
struct value_to_node_compare |
|
||||
: Pred |
|
||||
{ |
|
||||
typedef Pred predicate_type; |
|
||||
typedef Node node_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_to_node_compare() |
|
||||
: Pred() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit value_to_node_compare(Pred pred) |
|
||||
: Pred(pred) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a, const Node &b) const |
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data(), b.get_data()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a) const |
|
||||
{ return static_cast<const Pred&>(*this)(a.get_data()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a, const Node &b) |
|
||||
{ return static_cast<Pred&>(*this)(a.get_data(), b.get_data()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const Node &a) |
|
||||
{ return static_cast<Pred&>(*this)(a.get_data()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE predicate_type & predicate() { return static_cast<predicate_type&>(*this); } |
|
||||
BOOST_CONTAINER_FORCEINLINE const predicate_type & predicate() const { return static_cast<predicate_type&>(*this); } |
|
||||
}; |
|
||||
|
|
||||
template<class KeyPred, class KeyOfValue, class Node, class Ret = bool> |
|
||||
struct key_node_pred |
|
||||
: public boost::intrusive::detail::ebo_functor_holder<KeyPred> |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit key_node_pred(const KeyPred &comp) |
|
||||
: base_t(comp) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit key_node_pred() |
|
||||
{} |
|
||||
|
|
||||
typedef boost::intrusive::detail::ebo_functor_holder<KeyPred> base_t; |
|
||||
typedef KeyPred key_predicate; |
|
||||
typedef KeyOfValue key_of_value; |
|
||||
typedef typename KeyOfValue::type key_type; |
|
||||
|
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE static const key_type &key_from(const Node &n) |
|
||||
{ |
|
||||
return key_of_value()(n.get_data()); |
|
||||
} |
|
||||
|
|
||||
template <class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE static const T & |
|
||||
key_from(const T &t) |
|
||||
{ return t; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const key_predicate &key_pred() const |
|
||||
{ return static_cast<const key_predicate &>(*this); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE key_predicate &key_pred() |
|
||||
{ return static_cast<key_predicate &>(*this); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const key_type &key) const |
|
||||
{ return this->key_pred()(key); } |
|
||||
|
|
||||
template<class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE Ret operator()(const U &nonkey) const |
|
||||
{ return this->key_pred()(this->key_from(nonkey)); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const key_type &key2) const |
|
||||
{ return this->key_pred()(key1, key2); } |
|
||||
|
|
||||
template<class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const key_type &key1, const U &nonkey2) const |
|
||||
{ return this->key_pred()(key1, this->key_from(nonkey2)); } |
|
||||
|
|
||||
template<class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const key_type &key2) const |
|
||||
{ return this->key_pred()(this->key_from(nonkey1), key2); } |
|
||||
|
|
||||
template<class U, class V> |
|
||||
BOOST_CONTAINER_FORCEINLINE bool operator()(const U &nonkey1, const V &nonkey2) const |
|
||||
{ return this->key_pred()(this->key_from(nonkey1), this->key_from(nonkey2)); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_DETAIL_COMPARE_FUNCTORS_HPP
|
|
@ -1,61 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
|
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
#include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
#pragma warning (push)
|
|
||||
#pragma warning (disable : 4619) // there is no warning number 'XXXX'
|
|
||||
#pragma warning (disable : 4127) // conditional expression is constant
|
|
||||
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
|
||||
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
|
|
||||
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
|
|
||||
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
|
|
||||
#pragma warning (disable : 4284) // odd return type for operator->
|
|
||||
#pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
|
||||
#pragma warning (disable : 4324) // structure was padded due to __declspec(align(
|
|
||||
#pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
|
|
||||
#pragma warning (disable : 4355) // "this" : used in base member initializer list
|
|
||||
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
|
|
||||
#pragma warning (disable : 4510) // default constructor could not be generated
|
|
||||
#pragma warning (disable : 4511) // copy constructor could not be generated
|
|
||||
#pragma warning (disable : 4512) // assignment operator could not be generated
|
|
||||
#pragma warning (disable : 4514) // unreferenced inline removed
|
|
||||
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
|
|
||||
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
|
|
||||
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result
|
|
||||
#pragma warning (disable : 4584) // X is already a base-class of Y
|
|
||||
#pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required
|
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
|
||||
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
|
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
|
||||
#pragma warning (disable : 4710) // function not inlined
|
|
||||
#pragma warning (disable : 4714) // "function": marked as __forceinline not inlined
|
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
|
||||
|
|
||||
#endif //BOOST_MSVC
|
|
||||
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
//Sign conversion warnings broken before GCC 9.3
|
|
||||
//(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87519)
|
|
||||
#if BOOST_GCC < 90300
|
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
||||
#endif
|
|
||||
#endif
|
|
@ -1,16 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#if defined BOOST_MSVC
|
|
||||
#pragma warning (pop)
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#endif
|
|
@ -1,98 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/container/detail/iterators.hpp>
|
|
||||
#include <boost/container/detail/value_init.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
//In place construction
|
|
||||
|
|
||||
struct iterator_arg_t{}; |
|
||||
|
|
||||
template<class Allocator, class T, class InpIt> |
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source) |
|
||||
{ boost::container::allocator_traits<Allocator>::construct(a, dest, *source); } |
|
||||
|
|
||||
template<class Allocator, class T, class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator<U>) |
|
||||
{ |
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest); |
|
||||
} |
|
||||
|
|
||||
template <class T> |
|
||||
class default_init_construct_iterator; |
|
||||
|
|
||||
template<class Allocator, class T, class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator<U>) |
|
||||
{ |
|
||||
boost::container::allocator_traits<Allocator>::construct(a, dest, default_init); |
|
||||
} |
|
||||
|
|
||||
template <class T, class EmplaceFunctor> |
|
||||
class emplace_iterator; |
|
||||
|
|
||||
template<class Allocator, class T, class U, class EF> |
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator<U, EF> ei) |
|
||||
{ |
|
||||
ei.construct_in_place(a, dest); |
|
||||
} |
|
||||
|
|
||||
//Assignment
|
|
||||
|
|
||||
template<class DstIt, class InpIt> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source) |
|
||||
{ *dest = *source; } |
|
||||
|
|
||||
template<class DstIt, class U> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator<U>) |
|
||||
{ |
|
||||
dtl::value_init<U> val; |
|
||||
*dest = boost::move(val.get()); |
|
||||
} |
|
||||
|
|
||||
template <class DstIt> |
|
||||
class default_init_construct_iterator; |
|
||||
|
|
||||
template<class DstIt, class U, class D> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator<U>) |
|
||||
{ |
|
||||
U u; |
|
||||
*dest = boost::move(u); |
|
||||
} |
|
||||
|
|
||||
template <class T, class EmplaceFunctor> |
|
||||
class emplace_iterator; |
|
||||
|
|
||||
template<class DstIt, class U, class EF> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator<U, EF> ei) |
|
||||
{ |
|
||||
ei.assign_in_place(dest); |
|
||||
} |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP
|
|
@ -1,53 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/container/detail/container_rebind.hpp>
|
|
||||
#include <boost/container/detail/is_container.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class AllocatorOrContainer, class ToType, bool = is_container<AllocatorOrContainer>::value> |
|
||||
struct container_or_allocator_rebind_impl |
|
||||
: container_rebind<AllocatorOrContainer, ToType> |
|
||||
{}; |
|
||||
|
|
||||
template<class AllocatorOrContainer, class ToType> |
|
||||
struct container_or_allocator_rebind_impl<AllocatorOrContainer, ToType, false> |
|
||||
: allocator_traits<AllocatorOrContainer>::template portable_rebind_alloc<ToType> |
|
||||
{}; |
|
||||
|
|
||||
template<class ToType> |
|
||||
struct container_or_allocator_rebind_impl<void, ToType, false> |
|
||||
: real_allocator<ToType, void> |
|
||||
{}; |
|
||||
|
|
||||
template<class AllocatorOrContainer, class ToType> |
|
||||
struct container_or_allocator_rebind |
|
||||
: container_or_allocator_rebind_impl<AllocatorOrContainer, ToType> |
|
||||
{}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_OR_ALLOCATOR_REBIND_HPP
|
|
@ -1,163 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/container/container_fwd.hpp>
|
|
||||
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class Cont, class U> |
|
||||
struct container_rebind; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U> |
|
||||
struct container_rebind<Cont<V, A, An...>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, An...> type; |
|
||||
}; |
|
||||
|
|
||||
//Needed for non-conforming compilers like GCC 4.3
|
|
||||
template <template <class, class> class Cont, typename V, typename A, class U> |
|
||||
struct container_rebind<Cont<V, A>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class> class Cont, typename V, class U> |
|
||||
struct container_rebind<Cont<V>, U> |
|
||||
{ |
|
||||
typedef Cont<U> type; |
|
||||
}; |
|
||||
|
|
||||
#else //C++03 compilers
|
|
||||
|
|
||||
template <template <class> class Cont //0arg
|
|
||||
, typename V |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V>, U> |
|
||||
{ |
|
||||
typedef Cont<U> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class> class Cont //0arg
|
|
||||
, typename V, typename A |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class> class Cont //1arg
|
|
||||
, typename V, typename A, class P0 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class> class Cont //2arg
|
|
||||
, typename V, typename A, class P0, class P1 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class> class Cont //3arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class> class Cont //4arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class, class> class Cont //5arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class, class, class> class Cont //6arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class, class, class, class> class Cont //7arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class, class, class, class, class> class Cont //8arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type; |
|
||||
}; |
|
||||
|
|
||||
template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont //9arg
|
|
||||
, typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8 |
|
||||
, class U> |
|
||||
struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U> |
|
||||
{ |
|
||||
typedef Cont<U, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type; |
|
||||
}; |
|
||||
|
|
||||
#endif //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
//for small_vector,static_vector
|
|
||||
|
|
||||
template <typename V, std::size_t N, typename A, typename O, class U> |
|
||||
struct container_rebind<small_vector<V, N, A, O>, U> |
|
||||
{ |
|
||||
typedef small_vector<U, N, typename allocator_traits<typename real_allocator<V, A>::type>::template portable_rebind_alloc<U>::type, O> type; |
|
||||
}; |
|
||||
|
|
||||
template <typename V, std::size_t N, typename O, class U> |
|
||||
struct container_rebind<static_vector<V, N, O>, U> |
|
||||
{ |
|
||||
typedef static_vector<U, N, O> type; |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
|
|
1982
src/boost/container/detail/copy_move_algo.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,502 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
|
||||
#define BOOST_CONTAINER_DESTROYERS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
|
||||
#include <boost/container/detail/version_type.hpp>
|
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
|
||||
//!allocated for an object using a STL allocator.
|
|
||||
template <class Allocator> |
|
||||
struct scoped_deallocator |
|
||||
{ |
|
||||
typedef allocator_traits<Allocator> allocator_traits_type; |
|
||||
typedef typename allocator_traits_type::pointer pointer; |
|
||||
typedef dtl::integral_constant<unsigned, |
|
||||
boost::container::dtl:: |
|
||||
version<Allocator>::value> alloc_version; |
|
||||
|
|
||||
private: |
|
||||
void priv_deallocate(version_1) |
|
||||
{ m_alloc.deallocate(m_ptr, 1); } |
|
||||
|
|
||||
void priv_deallocate(version_2) |
|
||||
{ m_alloc.deallocate_one(m_ptr); } |
|
||||
|
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator) |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
pointer m_ptr; |
|
||||
Allocator& m_alloc; |
|
||||
|
|
||||
scoped_deallocator(pointer p, Allocator& a) |
|
||||
: m_ptr(p), m_alloc(a) |
|
||||
{} |
|
||||
|
|
||||
~scoped_deallocator() |
|
||||
{ if (m_ptr)priv_deallocate(alloc_version()); } |
|
||||
|
|
||||
scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o) |
|
||||
: m_ptr(o.m_ptr), m_alloc(o.m_alloc) |
|
||||
{ o.release(); } |
|
||||
|
|
||||
pointer get() const |
|
||||
{ return m_ptr; } |
|
||||
|
|
||||
void set(const pointer &p) |
|
||||
{ m_ptr = p; } |
|
||||
|
|
||||
void release() |
|
||||
{ m_ptr = 0; } |
|
||||
}; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
struct null_scoped_deallocator |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
|
|
||||
null_scoped_deallocator(pointer, Allocator&, std::size_t) |
|
||||
{} |
|
||||
|
|
||||
void release() |
|
||||
{} |
|
||||
|
|
||||
pointer get() const |
|
||||
{ return pointer(); } |
|
||||
|
|
||||
void set(const pointer &) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
//!A deleter for scoped_ptr that deallocates the memory
|
|
||||
//!allocated for an array of objects using a STL allocator.
|
|
||||
template <class Allocator> |
|
||||
struct scoped_array_deallocator |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
typedef typename AllocTraits::size_type size_type; |
|
||||
|
|
||||
scoped_array_deallocator(pointer p, Allocator& a, std::size_t length) |
|
||||
: m_ptr(p), m_alloc(a), m_length(length) {} |
|
||||
|
|
||||
~scoped_array_deallocator() |
|
||||
{ if (m_ptr) m_alloc.deallocate(m_ptr, size_type(m_length)); } |
|
||||
|
|
||||
void release() |
|
||||
{ m_ptr = 0; } |
|
||||
|
|
||||
private: |
|
||||
pointer m_ptr; |
|
||||
Allocator& m_alloc; |
|
||||
std::size_t m_length; |
|
||||
}; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
struct null_scoped_array_deallocator |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
|
|
||||
null_scoped_array_deallocator(pointer, Allocator&, std::size_t) |
|
||||
{} |
|
||||
|
|
||||
void release() |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
struct scoped_node_destroy_deallocator |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
typedef dtl::integral_constant<unsigned, |
|
||||
boost::container::dtl:: |
|
||||
version<Allocator>::value> alloc_version; |
|
||||
|
|
||||
scoped_node_destroy_deallocator(pointer p, Allocator& a) |
|
||||
: m_ptr(p), m_alloc(a) {} |
|
||||
|
|
||||
~scoped_node_destroy_deallocator() |
|
||||
{ |
|
||||
if(m_ptr){ |
|
||||
boost::movelib::to_raw_pointer(m_ptr)->destructor(m_alloc); |
|
||||
priv_deallocate(m_ptr, alloc_version()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void release() |
|
||||
{ m_ptr = 0; } |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
void priv_deallocate(const pointer &p, version_1) |
|
||||
{ AllocTraits::deallocate(m_alloc, p, 1); } |
|
||||
|
|
||||
void priv_deallocate(const pointer &p, version_2) |
|
||||
{ m_alloc.deallocate_one(p); } |
|
||||
|
|
||||
pointer m_ptr; |
|
||||
Allocator& m_alloc; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
//!A deleter for scoped_ptr that destroys
|
|
||||
//!an object using a STL allocator.
|
|
||||
template <class Allocator, class Ptr = typename allocator_traits<Allocator>::pointer> |
|
||||
struct scoped_destructor_n |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef Ptr pointer; |
|
||||
typedef typename AllocTraits::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(Ptr p, Allocator& a, std::size_t n) |
|
||||
: m_p(p), m_n(n), m_a(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{ m_p = Ptr(); m_n = 0; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t inc) |
|
||||
{ m_n += inc; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t inc) |
|
||||
{ m_n += inc; m_p -= std::ptrdiff_t(inc); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t inc) |
|
||||
{ m_n -= inc; m_p += std::ptrdiff_t(inc); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_size(std::size_t sz) |
|
||||
{ m_n = sz; } |
|
||||
|
|
||||
~scoped_destructor_n() |
|
||||
{ |
|
||||
if(m_n){ |
|
||||
value_type *raw_ptr = boost::movelib::iterator_to_raw_pointer(m_p); |
|
||||
do { |
|
||||
--m_n; |
|
||||
AllocTraits::destroy(m_a, raw_ptr); |
|
||||
++raw_ptr; |
|
||||
} while(m_n); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
pointer m_p; |
|
||||
std::size_t m_n; |
|
||||
Allocator& m_a; |
|
||||
}; |
|
||||
|
|
||||
//!A deleter for scoped_ptr that destroys
|
|
||||
//!an object using a STL allocator.
|
|
||||
template <class Allocator, class Ptr = typename allocator_traits<Allocator>::pointer> |
|
||||
struct null_scoped_destructor_n |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef Ptr pointer; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(Ptr, Allocator&, std::size_t) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size(std::size_t) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(std::size_t) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_size(std::size_t ) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void shrink_forward(std::size_t) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
//!A deleter for scoped_ptr that destroys
|
|
||||
//!an object using a STL allocator.
|
|
||||
template <class Allocator> |
|
||||
struct scoped_destructor_range |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
typedef typename AllocTraits::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a) |
|
||||
: m_p(p), m_e(e), m_a(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{ m_p = pointer(); m_e = pointer(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_end(pointer e) |
|
||||
{ m_e = e; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b) |
|
||||
{ m_p = b; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e) |
|
||||
{ m_p = b; m_e = e; } |
|
||||
|
|
||||
~scoped_destructor_range() |
|
||||
{ |
|
||||
while(m_p != m_e){ |
|
||||
value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); |
|
||||
AllocTraits::destroy(m_a, raw_ptr); |
|
||||
++m_p; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
pointer m_p; |
|
||||
pointer m_e; |
|
||||
Allocator & m_a; |
|
||||
}; |
|
||||
|
|
||||
//!A deleter for scoped_ptr that destroys
|
|
||||
//!an object using a STL allocator.
|
|
||||
template <class Allocator> |
|
||||
struct null_scoped_destructor_range |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_end(pointer) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_begin(pointer) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class Allocator> |
|
||||
class scoped_destructor |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
public: |
|
||||
typedef typename Allocator::value_type value_type; |
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv) |
|
||||
: pv_(pv), a_(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~scoped_destructor() |
|
||||
{ |
|
||||
if(pv_){ |
|
||||
AllocTraits::destroy(a_, pv_); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{ pv_ = 0; } |
|
||||
|
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; } |
|
||||
|
|
||||
private: |
|
||||
value_type *pv_; |
|
||||
Allocator &a_; |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
class null_scoped_destructor |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
public: |
|
||||
typedef typename Allocator::value_type value_type; |
|
||||
BOOST_CONTAINER_FORCEINLINE null_scoped_destructor(Allocator &, value_type *) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~null_scoped_destructor() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set(value_type *) { } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_type *get() const { return 0; } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
|
|
||||
template<class Allocator, class Value = typename Allocator::value_type> |
|
||||
class value_destructor |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
public: |
|
||||
typedef Value value_type; |
|
||||
BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv) |
|
||||
: rv_(rv), a_(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~value_destructor() |
|
||||
{ |
|
||||
AllocTraits::destroy(a_, &rv_); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
value_type &rv_; |
|
||||
Allocator &a_; |
|
||||
}; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
class allocator_node_destroyer |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
typedef typename AllocTraits::value_type value_type; |
|
||||
typedef typename AllocTraits::pointer pointer; |
|
||||
typedef dtl::integral_constant<unsigned, |
|
||||
boost::container::dtl:: |
|
||||
version<Allocator>::value> alloc_version; |
|
||||
|
|
||||
private: |
|
||||
Allocator & a_; |
|
||||
|
|
||||
private: |
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1) |
|
||||
{ AllocTraits::deallocate(a_,p, 1); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2) |
|
||||
{ a_.deallocate_one(p); } |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit allocator_node_destroyer(Allocator &a) |
|
||||
: a_(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p) |
|
||||
{ |
|
||||
boost::movelib::to_raw_pointer(p)->destructor(a_); |
|
||||
this->priv_deallocate(p, alloc_version()); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<class Allocator> |
|
||||
class scoped_node_destructor |
|
||||
{ |
|
||||
typedef boost::container::allocator_traits<Allocator> AllocTraits; |
|
||||
public: |
|
||||
typedef typename Allocator::value_type value_type; |
|
||||
BOOST_CONTAINER_FORCEINLINE scoped_node_destructor(Allocator &a, value_type *pv) |
|
||||
: pv_(pv), a_(a) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~scoped_node_destructor() |
|
||||
{ |
|
||||
if(pv_){ |
|
||||
pv_->destructor(a_); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void release() |
|
||||
{ pv_ = 0; } |
|
||||
|
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; } |
|
||||
|
|
||||
private: |
|
||||
value_type *pv_; |
|
||||
Allocator &a_; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
|
|
||||
template <class Allocator> |
|
||||
class allocator_node_destroyer_and_chain_builder |
|
||||
{ |
|
||||
typedef allocator_traits<Allocator> allocator_traits_type; |
|
||||
typedef typename allocator_traits_type::value_type value_type; |
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain; |
|
||||
|
|
||||
Allocator & a_; |
|
||||
multiallocation_chain &c_; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_node_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) |
|
||||
: a_(a), c_(c) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p) |
|
||||
{ |
|
||||
boost::movelib::to_raw_pointer(p)->destructor(a_); |
|
||||
c_.push_back(p); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template <class Allocator> |
|
||||
class allocator_multialloc_chain_node_deallocator |
|
||||
{ |
|
||||
typedef allocator_traits<Allocator> allocator_traits_type; |
|
||||
typedef typename allocator_traits_type::value_type value_type; |
|
||||
typedef typename Allocator::multiallocation_chain multiallocation_chain; |
|
||||
typedef allocator_node_destroyer_and_chain_builder<Allocator> chain_builder; |
|
||||
|
|
||||
Allocator & a_; |
|
||||
multiallocation_chain c_; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a) |
|
||||
: a_(a), c_() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder() |
|
||||
{ return chain_builder(a_, c_); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator() |
|
||||
{ |
|
||||
a_.deallocate_individual(c_); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP
|
|
1711
src/boost/container/detail/flat_tree.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,72 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
|
||||
#endif
|
|
||||
|
|
||||
//empty
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME empty
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
//size
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME size
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_container_detail {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
//#pragma GCC diagnostic ignored "-Wunused-result"
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class Container> |
|
||||
struct is_container |
|
||||
{ |
|
||||
static const bool value = |
|
||||
boost::container::is_container_detail:: |
|
||||
has_member_function_callable_with_size <const Container>::value && |
|
||||
boost::container::is_container_detail:: |
|
||||
has_member_function_callable_with_empty<const Container>::value; |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct is_container<void> |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTAINER_HPP
|
|
@ -1,82 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
#pragma GCC diagnostic ignored "-Wunused-result"
|
|
||||
#endif
|
|
||||
|
|
||||
//data
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME data
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace is_contiguous_container_detail {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
//back_free_capacity
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME back_free_capacity
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace back_free_capacity_detail {
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 0
|
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 0
|
|
||||
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
|
|
||||
|
|
||||
//#pragma GCC diagnostic ignored "-Wunused-result"
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class Container> |
|
||||
struct is_contiguous_container |
|
||||
{ |
|
||||
static const bool value = |
|
||||
boost::container::is_contiguous_container_detail:: |
|
||||
has_member_function_callable_with_data<Container>::value && |
|
||||
boost::container::is_contiguous_container_detail:: |
|
||||
has_member_function_callable_with_data<const Container>::value; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template < class Container |
|
||||
, bool = boost::container::back_free_capacity_detail:: |
|
||||
has_member_function_callable_with_back_free_capacity<const Container>::value> |
|
||||
struct back_free_capacity |
|
||||
{ |
|
||||
static typename Container::size_type get(const Container &c) |
|
||||
{ return c.back_free_capacity(); } |
|
||||
}; |
|
||||
|
|
||||
template < class Container> |
|
||||
struct back_free_capacity<Container, false> |
|
||||
{ |
|
||||
static typename Container::size_type get(const Container &c) |
|
||||
{ return c.capacity() - c.size(); } |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_CONTIGUOUS_CONTAINER_HPP
|
|
@ -1,91 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP
|
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
|
||||
|
|
||||
#if defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
|
||||
//MSVC 2010 tuple marker
|
|
||||
namespace std { namespace tr1 { struct _Nil; }} |
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
|
||||
//MSVC 2012 tuple marker
|
|
||||
namespace std { struct _Nil; } |
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace tuples { |
|
||||
|
|
||||
struct null_type; |
|
||||
|
|
||||
template < |
|
||||
class T0, class T1, class T2, |
|
||||
class T3, class T4, class T5, |
|
||||
class T6, class T7, class T8, |
|
||||
class T9> |
|
||||
class tuple; |
|
||||
|
|
||||
} //namespace tuples {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
struct try_emplace_t{}; |
|
||||
|
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct pair; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_pair |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_pair< pair<T1, T2> > |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_pair< std::pair<T1, T2> > |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_not_pair |
|
||||
{ |
|
||||
static const bool value = !is_pair<T>::value; |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_IS_PAIR_HPP
|
|
@ -1,57 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class ForwardIterator, class Pred> |
|
||||
bool is_sorted (ForwardIterator first, ForwardIterator last, Pred pred) |
|
||||
{ |
|
||||
if(first != last){ |
|
||||
ForwardIterator next = first; |
|
||||
while (++next != last){ |
|
||||
if(pred(*next, *first)) |
|
||||
return false; |
|
||||
++first; |
|
||||
} |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
template <class ForwardIterator, class Pred> |
|
||||
bool is_sorted_and_unique (ForwardIterator first, ForwardIterator last, Pred pred) |
|
||||
{ |
|
||||
if(first != last){ |
|
||||
ForwardIterator next = first; |
|
||||
while (++next != last){ |
|
||||
if(!pred(*first, *next)) |
|
||||
return false; |
|
||||
++first; |
|
||||
} |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_IS_SORTED_HPP
|
|
@ -1,94 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/intrusive/detail/iterator.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
using ::boost::intrusive::iterator_traits; |
|
||||
using ::boost::intrusive::iter_difference; |
|
||||
using ::boost::intrusive::iter_category; |
|
||||
using ::boost::intrusive::iter_value; |
|
||||
using ::boost::intrusive::iter_size; |
|
||||
using ::boost::intrusive::iterator_distance; |
|
||||
using ::boost::intrusive::iterator_udistance; |
|
||||
using ::boost::intrusive::iterator_advance; |
|
||||
using ::boost::intrusive::iterator_uadvance; |
|
||||
using ::boost::intrusive::make_iterator_advance; |
|
||||
using ::boost::intrusive::make_iterator_uadvance; |
|
||||
using ::boost::intrusive::iterator; |
|
||||
using ::boost::intrusive::iterator_enable_if_tag; |
|
||||
using ::boost::intrusive::iterator_disable_if_tag; |
|
||||
using ::boost::intrusive::iterator_arrow_result; |
|
||||
|
|
||||
template <class Container> |
|
||||
class back_emplacer |
|
||||
{ |
|
||||
private: |
|
||||
Container& container; |
|
||||
|
|
||||
public: |
|
||||
typedef std::output_iterator_tag iterator_category; |
|
||||
typedef void value_type; |
|
||||
typedef void difference_type; |
|
||||
typedef void pointer; |
|
||||
typedef void reference; |
|
||||
|
|
||||
back_emplacer(Container& x) |
|
||||
: container(x) |
|
||||
{} |
|
||||
|
|
||||
template<class U> |
|
||||
back_emplacer& operator=(BOOST_FWD_REF(U) value) |
|
||||
{ |
|
||||
container.emplace_back(boost::forward<U>(value)); |
|
||||
return *this; |
|
||||
} |
|
||||
back_emplacer& operator*() { return *this; } |
|
||||
back_emplacer& operator++() { return *this; } |
|
||||
back_emplacer& operator++(int){ return *this; } |
|
||||
}; |
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
|
|
||||
|
|
||||
template<class InputIterator> |
|
||||
using it_based_non_const_first_type_t = typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type; |
|
||||
|
|
||||
template<class InputIterator> |
|
||||
using it_based_const_first_type_t = const typename dtl::remove_const<typename iterator_traits<InputIterator>::value_type::first_type>::type; |
|
||||
|
|
||||
template<class InputIterator> |
|
||||
using it_based_second_type_t = typename iterator_traits<InputIterator>::value_type::second_type; |
|
||||
|
|
||||
template<class InputIterator> |
|
||||
using it_based_value_type_t = typename iterator_traits<InputIterator>::value_type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
|
@ -1,910 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/value_init.hpp>
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/intrusive/detail/reverse_iterator.hpp>
|
|
||||
|
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
|
||||
#else
|
|
||||
#include <boost/container/detail/variadic_templates_tools.hpp>
|
|
||||
#endif
|
|
||||
#include <boost/container/detail/iterator.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
template <class T> |
|
||||
class constant_iterator |
|
||||
: public ::boost::container::iterator |
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> |
|
||||
{ |
|
||||
typedef constant_iterator<T> this_type; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit constant_iterator(const T &ref, std::size_t range_size) |
|
||||
: m_ptr(&ref), m_num(range_size){} |
|
||||
|
|
||||
//Constructors
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator() |
|
||||
: m_ptr(0), m_num(0){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator++(int) |
|
||||
{ |
|
||||
constant_iterator result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator--() |
|
||||
{ decrement(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator--(int) |
|
||||
{ |
|
||||
constant_iterator result (*this); |
|
||||
decrement(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return i.less(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return !(i < i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const constant_iterator& i, const constant_iterator& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic signed
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::ptrdiff_t off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::ptrdiff_t off) const |
|
||||
{ |
|
||||
constant_iterator other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::ptrdiff_t off, const constant_iterator& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::ptrdiff_t off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::ptrdiff_t off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::ptrdiff_t ) const |
|
||||
{ return dereference(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T& operator*() const |
|
||||
{ return dereference(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T* operator->() const |
|
||||
{ return &(dereference()); } |
|
||||
|
|
||||
//Arithmetic unsigned
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::size_t off) |
|
||||
{ return *this += std::ptrdiff_t(off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::size_t off) const |
|
||||
{ return *this + std::ptrdiff_t(off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::size_t off, const constant_iterator& right) |
|
||||
{ return std::ptrdiff_t(off) + right; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::size_t off) |
|
||||
{ return *this -= std::ptrdiff_t(off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::size_t off) const |
|
||||
{ return *this - std::ptrdiff_t(off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::size_t off) const |
|
||||
{ return (*this)[std::ptrdiff_t(off)]; } |
|
||||
|
|
||||
private: |
|
||||
const T * m_ptr; |
|
||||
std::size_t m_num; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ --m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ ++m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const |
|
||||
{ return m_num == other.m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const |
|
||||
{ return other.m_num < m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const |
|
||||
{ return *m_ptr; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) |
|
||||
{ m_num = std::size_t(std::ptrdiff_t(m_num) - n); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const |
|
||||
{ return std::ptrdiff_t(m_num - other.m_num); } |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
class value_init_construct_iterator |
|
||||
: public ::boost::container::iterator |
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> |
|
||||
{ |
|
||||
typedef value_init_construct_iterator<T> this_type; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit value_init_construct_iterator(std::size_t range_size) |
|
||||
: m_num(range_size){} |
|
||||
|
|
||||
//Constructors
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator() |
|
||||
: m_num(0){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator++(int) |
|
||||
{ |
|
||||
value_init_construct_iterator result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator--() |
|
||||
{ decrement(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator--(int) |
|
||||
{ |
|
||||
value_init_construct_iterator result (*this); |
|
||||
decrement(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return i.less(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return !(i < i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator+=(std::ptrdiff_t off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator+(std::ptrdiff_t off) const |
|
||||
{ |
|
||||
value_init_construct_iterator other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend value_init_construct_iterator operator+(std::ptrdiff_t off, const value_init_construct_iterator& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator-=(std::ptrdiff_t off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator-(std::ptrdiff_t off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
|
||||
//So comment them to catch bad uses
|
|
||||
//const T& operator*() const;
|
|
||||
//const T& operator[](difference_type) const;
|
|
||||
//const T* operator->() const;
|
|
||||
|
|
||||
private: |
|
||||
std::size_t m_num; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ --m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ ++m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const |
|
||||
{ return m_num == other.m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const |
|
||||
{ return other.m_num < m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const |
|
||||
{ |
|
||||
static T dummy; |
|
||||
return dummy; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) |
|
||||
{ m_num = std::size_t(std::ptrdiff_t(m_num) - n); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const |
|
||||
{ return std::ptrdiff_t(m_num - other.m_num); } |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
class default_init_construct_iterator |
|
||||
: public ::boost::container::iterator |
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> |
|
||||
{ |
|
||||
typedef default_init_construct_iterator<T> this_type; |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit default_init_construct_iterator(std::size_t range_size) |
|
||||
: m_num(range_size){} |
|
||||
|
|
||||
//Constructors
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator() |
|
||||
: m_num(0){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator++(int) |
|
||||
{ |
|
||||
default_init_construct_iterator result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator--() |
|
||||
{ decrement(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator--(int) |
|
||||
{ |
|
||||
default_init_construct_iterator result (*this); |
|
||||
decrement(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return i.less(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return !(i < i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator+=(std::ptrdiff_t off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator+(std::ptrdiff_t off) const |
|
||||
{ |
|
||||
default_init_construct_iterator other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend default_init_construct_iterator operator+(std::ptrdiff_t off, const default_init_construct_iterator& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator-=(std::ptrdiff_t off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator-(std::ptrdiff_t off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
|
||||
//So comment them to catch bad uses
|
|
||||
//const T& operator*() const;
|
|
||||
//const T& operator[](difference_type) const;
|
|
||||
//const T* operator->() const;
|
|
||||
|
|
||||
private: |
|
||||
std::size_t m_num; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ --m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ ++m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const |
|
||||
{ return m_num == other.m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const |
|
||||
{ return other.m_num < m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const |
|
||||
{ |
|
||||
static T dummy; |
|
||||
return dummy; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) |
|
||||
{ m_num = std::size_t(std::ptrdiff_t(m_num) - n); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other) const |
|
||||
{ return std::ptrdiff_t(m_num - other.m_num); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template <class T> |
|
||||
class repeat_iterator |
|
||||
: public ::boost::container::iterator |
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&> |
|
||||
{ |
|
||||
typedef repeat_iterator<T> this_type; |
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit repeat_iterator(T &ref, std::size_t range_size) |
|
||||
: m_ptr(&ref), m_num(range_size){} |
|
||||
|
|
||||
//Constructors
|
|
||||
BOOST_CONTAINER_FORCEINLINE repeat_iterator() |
|
||||
: m_ptr(0), m_num(0){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator++(int) |
|
||||
{ |
|
||||
this_type result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator--(int) |
|
||||
{ |
|
||||
this_type result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) |
|
||||
{ return i.less(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i < i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator+=(std::ptrdiff_t off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator+(std::ptrdiff_t off) const |
|
||||
{ |
|
||||
this_type other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(std::ptrdiff_t off, const this_type& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(std::ptrdiff_t off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(std::ptrdiff_t off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T& operator*() const |
|
||||
{ return dereference(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T& operator[] (std::ptrdiff_t ) const |
|
||||
{ return dereference(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T *operator->() const |
|
||||
{ return &(dereference()); } |
|
||||
|
|
||||
private: |
|
||||
T * m_ptr; |
|
||||
std::size_t m_num; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ --m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ ++m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const |
|
||||
{ return m_num == other.m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const |
|
||||
{ return other.m_num < m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T & dereference() const |
|
||||
{ return *m_ptr; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n) |
|
||||
{ m_num = std::size_t(std::ptrdiff_t(m_num - n)); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const |
|
||||
{ return std::ptrdiff_t(m_num - other.m_num); } |
|
||||
}; |
|
||||
|
|
||||
template <class T, class EmplaceFunctor> |
|
||||
class emplace_iterator |
|
||||
: public ::boost::container::iterator |
|
||||
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &> |
|
||||
{ |
|
||||
typedef emplace_iterator this_type; |
|
||||
|
|
||||
public: |
|
||||
typedef std::ptrdiff_t difference_type; |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e) |
|
||||
: m_num(1), m_pe(&e){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE emplace_iterator() |
|
||||
: m_num(0), m_pe(0){} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator++(int) |
|
||||
{ |
|
||||
this_type result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator--() |
|
||||
{ decrement(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator--(int) |
|
||||
{ |
|
||||
this_type result (*this); |
|
||||
decrement(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) |
|
||||
{ return i.less(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) |
|
||||
{ return !(i < i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator+(difference_type off) const |
|
||||
{ |
|
||||
this_type other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
private: |
|
||||
//This pseudo-iterator's dereference operations have no sense since value is not
|
|
||||
//constructed until ::boost::container::construct_in_place is called.
|
|
||||
//So comment them to catch bad uses
|
|
||||
const T& operator*() const; |
|
||||
const T& operator[](difference_type) const; |
|
||||
const T* operator->() const; |
|
||||
|
|
||||
public: |
|
||||
template<class Allocator> |
|
||||
BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* ptr) |
|
||||
{ (*m_pe)(a, ptr); } |
|
||||
|
|
||||
template<class DestIt> |
|
||||
BOOST_CONTAINER_FORCEINLINE void assign_in_place(DestIt dest) |
|
||||
{ (*m_pe)(dest); } |
|
||||
|
|
||||
private: |
|
||||
std::size_t m_num; |
|
||||
EmplaceFunctor * m_pe; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ --m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ ++m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const |
|
||||
{ return m_num == other.m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const |
|
||||
{ return other.m_num < m_num; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T & dereference() const |
|
||||
{ |
|
||||
static T dummy; |
|
||||
return dummy; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(difference_type n) |
|
||||
{ m_num -= n; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const |
|
||||
{ return difference_type(m_num - other.m_num); } |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class ...Args> |
|
||||
struct emplace_functor |
|
||||
{ |
|
||||
typedef typename dtl::build_number_seq<sizeof...(Args)>::type index_tuple_t; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE emplace_functor(BOOST_FWD_REF(Args)... args) |
|
||||
: args_(args...) |
|
||||
{} |
|
||||
|
|
||||
template<class Allocator, class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr) |
|
||||
{ emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } |
|
||||
|
|
||||
template<class DestIt> |
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest) |
|
||||
{ emplace_functor::inplace_impl(dest, index_tuple_t()); } |
|
||||
|
|
||||
private: |
|
||||
template<class Allocator, class T, std::size_t ...IdxPack> |
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple<IdxPack...>&) |
|
||||
{ |
|
||||
allocator_traits<Allocator>::construct |
|
||||
(a, ptr, ::boost::forward<Args>(dtl::get<IdxPack>(args_))...); |
|
||||
} |
|
||||
|
|
||||
template<class DestIt, std::size_t ...IdxPack> |
|
||||
BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple<IdxPack...>&) |
|
||||
{ |
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type; |
|
||||
value_type && tmp= value_type(::boost::forward<Args>(dtl::get<IdxPack>(args_))...); |
|
||||
*dest = ::boost::move(tmp); |
|
||||
} |
|
||||
|
|
||||
dtl::tuple<Args&...> args_; |
|
||||
}; |
|
||||
|
|
||||
template<class ...Args> |
|
||||
struct emplace_functor_type |
|
||||
{ |
|
||||
typedef emplace_functor<Args...> type; |
|
||||
}; |
|
||||
|
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
//Partial specializations cannot match argument list for primary template, so add an extra argument
|
|
||||
template <BOOST_MOVE_CLASSDFLT9, class Dummy = void> |
|
||||
struct emplace_functor_type; |
|
||||
|
|
||||
#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
|
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ |
|
||||
struct emplace_functor##N\ |
|
||||
{\ |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ |
|
||||
BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ |
|
||||
\ |
|
||||
template<class Allocator, class T>\ |
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)\ |
|
||||
{ allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ |
|
||||
\ |
|
||||
template<class DestIt>\ |
|
||||
BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)\ |
|
||||
{\ |
|
||||
typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\ |
|
||||
BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init<value_type> tmp) ;\ |
|
||||
*dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\ |
|
||||
}\ |
|
||||
\ |
|
||||
BOOST_MOVE_MREF##N\ |
|
||||
};\ |
|
||||
\ |
|
||||
template <BOOST_MOVE_CLASS##N>\ |
|
||||
struct emplace_functor_type<BOOST_MOVE_TARG##N>\ |
|
||||
{\ |
|
||||
typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\ |
|
||||
};\ |
|
||||
//
|
|
||||
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE) |
|
||||
|
|
||||
#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class T> |
|
||||
struct has_iterator_category |
|
||||
{ |
|
||||
struct two { char _[2]; }; |
|
||||
|
|
||||
template <typename X> |
|
||||
static char test(int, typename X::iterator_category*); |
|
||||
|
|
||||
template <typename X> |
|
||||
static two test(int, ...); |
|
||||
|
|
||||
static const bool value = (1 == sizeof(test<T>(0, 0))); |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class T, bool = has_iterator_category<T>::value > |
|
||||
struct is_input_iterator |
|
||||
{ |
|
||||
static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_input_iterator<T, false> |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_not_input_iterator |
|
||||
{ |
|
||||
static const bool value = !is_input_iterator<T>::value; |
|
||||
}; |
|
||||
|
|
||||
template<class T, bool = has_iterator_category<T>::value > |
|
||||
struct is_forward_iterator |
|
||||
{ |
|
||||
static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_forward_iterator<T, false> |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T, bool = has_iterator_category<T>::value > |
|
||||
struct is_bidirectional_iterator |
|
||||
{ |
|
||||
static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_bidirectional_iterator<T, false> |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class IINodeType> |
|
||||
struct iiterator_node_value_type { |
|
||||
typedef typename IINodeType::value_type type; |
|
||||
}; |
|
||||
|
|
||||
template<class IIterator> |
|
||||
struct iiterator_types |
|
||||
{ |
|
||||
typedef typename IIterator::value_type it_value_type; |
|
||||
typedef typename iiterator_node_value_type<it_value_type>::type value_type; |
|
||||
typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer; |
|
||||
typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type; |
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: |
|
||||
template rebind_pointer<value_type>::type pointer; |
|
||||
typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: |
|
||||
template rebind_pointer<const value_type>::type const_pointer; |
|
||||
typedef typename ::boost::intrusive:: |
|
||||
pointer_traits<pointer>::reference reference; |
|
||||
typedef typename ::boost::intrusive:: |
|
||||
pointer_traits<const_pointer>::reference const_reference; |
|
||||
typedef typename IIterator::iterator_category iterator_category; |
|
||||
}; |
|
||||
|
|
||||
template<class IIterator, bool IsConst> |
|
||||
struct iterator_types |
|
||||
{ |
|
||||
typedef typename ::boost::container::iterator |
|
||||
< typename iiterator_types<IIterator>::iterator_category |
|
||||
, typename iiterator_types<IIterator>::value_type |
|
||||
, typename iiterator_types<IIterator>::difference_type |
|
||||
, typename iiterator_types<IIterator>::const_pointer |
|
||||
, typename iiterator_types<IIterator>::const_reference> type; |
|
||||
}; |
|
||||
|
|
||||
template<class IIterator> |
|
||||
struct iterator_types<IIterator, false> |
|
||||
{ |
|
||||
typedef typename ::boost::container::iterator |
|
||||
< typename iiterator_types<IIterator>::iterator_category |
|
||||
, typename iiterator_types<IIterator>::value_type |
|
||||
, typename iiterator_types<IIterator>::difference_type |
|
||||
, typename iiterator_types<IIterator>::pointer |
|
||||
, typename iiterator_types<IIterator>::reference> type; |
|
||||
}; |
|
||||
|
|
||||
template<class IIterator, bool IsConst> |
|
||||
class iterator_from_iiterator |
|
||||
{ |
|
||||
typedef typename iterator_types<IIterator, IsConst>::type types_t; |
|
||||
class nat |
|
||||
{ |
|
||||
public: |
|
||||
IIterator get() const |
|
||||
{ return IIterator(); } |
|
||||
}; |
|
||||
typedef typename dtl::if_c< IsConst |
|
||||
, iterator_from_iiterator<IIterator, false> |
|
||||
, nat>::type nonconst_iterator; |
|
||||
|
|
||||
public: |
|
||||
typedef typename types_t::pointer pointer; |
|
||||
typedef typename types_t::reference reference; |
|
||||
typedef typename types_t::difference_type difference_type; |
|
||||
typedef typename types_t::iterator_category iterator_category; |
|
||||
typedef typename types_t::value_type value_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator() |
|
||||
: m_iit() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
: m_iit(iit) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
: m_iit(other.get()) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
: m_iit(other.get()) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator=(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ m_iit = other.get(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ ++this->m_iit; return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
iterator_from_iiterator result (*this); |
|
||||
++this->m_iit; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
//If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
|
|
||||
BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value)); |
|
||||
--this->m_iit; return *this; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
iterator_from_iiterator result (*this); |
|
||||
--this->m_iit; |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return l.m_iit == r.m_iit; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return l.m_iit != r.m_iit; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return this->m_iit->get_data(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return this->m_iit; } |
|
||||
|
|
||||
private: |
|
||||
IIterator m_iit; |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
|
|
||||
using ::boost::intrusive::reverse_iterator; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
|
@ -1,37 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class T> |
|
||||
const T &max_value(const T &a, const T &b) |
|
||||
{ return a > b ? a : b; } |
|
||||
|
|
||||
template<class T> |
|
||||
const T &min_value(const T &a, const T &b) |
|
||||
{ return a < b ? a : b; } |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP
|
|
@ -1,32 +0,0 @@ |
|||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
|
||||
#
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
#
|
|
||||
#//Try to avoid including <string>, as it's quite big
|
|
||||
#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
|
|
||||
#include <iosfwd> //Dinkum libraries for MSVC define std::char_traits there
|
|
||||
#elif defined(BOOST_GNU_STDLIB)
|
|
||||
#include <bits/char_traits.h>
|
|
||||
#else
|
|
||||
#include <string> //Fallback
|
|
||||
#endif
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_DETAIL_MINIMAL_CHAR_TRAITS_HEADER_HPP
|
|
@ -1,144 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/move/detail/type_traits.hpp>
|
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
|
||||
|
|
||||
#include <cstddef>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
using boost::move_detail::integral_constant; |
|
||||
using boost::move_detail::true_type; |
|
||||
using boost::move_detail::false_type; |
|
||||
using boost::move_detail::enable_if_c; |
|
||||
using boost::move_detail::enable_if; |
|
||||
using boost::move_detail::enable_if_convertible; |
|
||||
using boost::move_detail::disable_if_c; |
|
||||
using boost::move_detail::disable_if; |
|
||||
using boost::move_detail::disable_if_convertible; |
|
||||
using boost::move_detail::is_convertible; |
|
||||
using boost::move_detail::if_c; |
|
||||
using boost::move_detail::if_; |
|
||||
using boost::move_detail::identity; |
|
||||
using boost::move_detail::bool_; |
|
||||
using boost::move_detail::true_; |
|
||||
using boost::move_detail::false_; |
|
||||
using boost::move_detail::yes_type; |
|
||||
using boost::move_detail::no_type; |
|
||||
using boost::move_detail::bool_; |
|
||||
using boost::move_detail::true_; |
|
||||
using boost::move_detail::false_; |
|
||||
using boost::move_detail::unvoid_ref; |
|
||||
using boost::move_detail::and_; |
|
||||
using boost::move_detail::or_; |
|
||||
using boost::move_detail::not_; |
|
||||
using boost::move_detail::enable_if_and; |
|
||||
using boost::move_detail::disable_if_and; |
|
||||
using boost::move_detail::enable_if_or; |
|
||||
using boost::move_detail::disable_if_or; |
|
||||
using boost::move_detail::remove_const; |
|
||||
|
|
||||
template <class FirstType> |
|
||||
struct select1st |
|
||||
{ |
|
||||
typedef FirstType type; |
|
||||
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE const type& operator()(const T& x) const |
|
||||
{ return x.first; } |
|
||||
|
|
||||
template<class T> |
|
||||
BOOST_CONTAINER_FORCEINLINE type& operator()(T& x) |
|
||||
{ return const_cast<type&>(x.first); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<typename T> |
|
||||
struct void_t { typedef void type; }; |
|
||||
|
|
||||
template <class T, class=void> |
|
||||
struct is_transparent_base |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_transparent_base<T, typename void_t<typename T::is_transparent>::type> |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_transparent |
|
||||
: is_transparent_base<T> |
|
||||
{}; |
|
||||
|
|
||||
template <typename C, class /*Dummy*/, typename R> |
|
||||
struct enable_if_transparent |
|
||||
: boost::move_detail::enable_if_c<dtl::is_transparent<C>::value, R> |
|
||||
{}; |
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_NO_CXX17_CTAD
|
|
||||
|
|
||||
// void_t (void_t for C++11)
|
|
||||
template<typename...> using variadic_void_t = void; |
|
||||
|
|
||||
// Trait to detect Allocator-like types.
|
|
||||
template<typename Allocator, typename = void> |
|
||||
struct is_allocator |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
T&& ctad_declval(); |
|
||||
|
|
||||
template<typename Allocator> |
|
||||
struct is_allocator < Allocator, |
|
||||
variadic_void_t< typename Allocator::value_type |
|
||||
, decltype(ctad_declval<Allocator&>().allocate(size_t{})) >> |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
using require_allocator_t = typename enable_if_c<is_allocator<T>::value, T>::type; |
|
||||
|
|
||||
template<class T> |
|
||||
using require_nonallocator_t = typename enable_if_c<!is_allocator<T>::value, T>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
|
|
||||
|
|
@ -1,307 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
// container
|
|
||||
#include <boost/container/container_fwd.hpp>
|
|
||||
// container/detail
|
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
|
||||
#include <boost/container/detail/transform_iterator.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
// intrusive
|
|
||||
#include <boost/intrusive/slist.hpp>
|
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
|
||||
#include <boost/intrusive/detail/twin.hpp>
|
|
||||
// move
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class VoidPointer> |
|
||||
class basic_multiallocation_chain |
|
||||
{ |
|
||||
private: |
|
||||
typedef bi::slist_base_hook<bi::void_pointer<VoidPointer> |
|
||||
,bi::link_mode<bi::normal_link> |
|
||||
> node; |
|
||||
|
|
||||
typedef typename boost::intrusive::pointer_traits |
|
||||
<VoidPointer>::template rebind_pointer<char>::type char_ptr; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<char_ptr>::difference_type difference_type; |
|
||||
|
|
||||
typedef bi::slist< node |
|
||||
, bi::linear<true> |
|
||||
, bi::cache_last<true> |
|
||||
, bi::size_type<typename boost::container::dtl::make_unsigned<difference_type>::type> |
|
||||
> slist_impl_t; |
|
||||
slist_impl_t slist_impl_; |
|
||||
|
|
||||
typedef typename boost::intrusive::pointer_traits |
|
||||
<VoidPointer>::template rebind_pointer<node>::type node_ptr; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<node_ptr> node_ptr_traits; |
|
||||
|
|
||||
static node & to_node(const VoidPointer &p) |
|
||||
{ return *static_cast<node*>(static_cast<void*>(boost::movelib::to_raw_pointer(p))); } |
|
||||
|
|
||||
static VoidPointer from_node(node &n) |
|
||||
{ return node_ptr_traits::pointer_to(n); } |
|
||||
|
|
||||
static node_ptr to_node_ptr(const VoidPointer &p) |
|
||||
{ return node_ptr_traits::static_cast_from(p); } |
|
||||
|
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain) |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
typedef VoidPointer void_pointer; |
|
||||
typedef typename slist_impl_t::iterator iterator; |
|
||||
typedef typename slist_impl_t::size_type size_type; |
|
||||
typedef boost::intrusive::twin<void_pointer> pointer_pair; |
|
||||
|
|
||||
basic_multiallocation_chain() |
|
||||
: slist_impl_() |
|
||||
{} |
|
||||
|
|
||||
basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n) |
|
||||
: slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n) |
|
||||
{} |
|
||||
|
|
||||
basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other) |
|
||||
: slist_impl_(::boost::move(other.slist_impl_)) |
|
||||
{} |
|
||||
|
|
||||
basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other) |
|
||||
{ |
|
||||
slist_impl_ = ::boost::move(other.slist_impl_); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
bool empty() const |
|
||||
{ return slist_impl_.empty(); } |
|
||||
|
|
||||
size_type size() const |
|
||||
{ return slist_impl_.size(); } |
|
||||
|
|
||||
iterator before_begin() |
|
||||
{ return slist_impl_.before_begin(); } |
|
||||
|
|
||||
iterator begin() |
|
||||
{ return slist_impl_.begin(); } |
|
||||
|
|
||||
iterator end() |
|
||||
{ return slist_impl_.end(); } |
|
||||
|
|
||||
iterator last() |
|
||||
{ return slist_impl_.last(); } |
|
||||
|
|
||||
void clear() |
|
||||
{ slist_impl_.clear(); } |
|
||||
|
|
||||
iterator insert_after(iterator it, void_pointer m) |
|
||||
{ return slist_impl_.insert_after(it, to_node(m)); } |
|
||||
|
|
||||
void push_front(const void_pointer &m) |
|
||||
{ return slist_impl_.push_front(to_node(m)); } |
|
||||
|
|
||||
void push_back(const void_pointer &m) |
|
||||
{ return slist_impl_.push_back(to_node(m)); } |
|
||||
|
|
||||
void_pointer pop_front() |
|
||||
{ |
|
||||
node & n = slist_impl_.front(); |
|
||||
void_pointer ret = from_node(n); |
|
||||
slist_impl_.pop_front(); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) |
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); } |
|
||||
|
|
||||
void splice_after(iterator after_this, basic_multiallocation_chain &x) |
|
||||
{ slist_impl_.splice_after(after_this, x.slist_impl_); } |
|
||||
|
|
||||
void erase_after(iterator before_b, iterator e, size_type n) |
|
||||
{ slist_impl_.erase_after(before_b, e, n); } |
|
||||
|
|
||||
void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units) |
|
||||
{ |
|
||||
typedef typename boost::intrusive::pointer_traits<char_ptr> char_pointer_traits; |
|
||||
char_ptr elem = char_pointer_traits::static_cast_from(b); |
|
||||
if(num_units){ |
|
||||
char_ptr prev_elem = elem; |
|
||||
elem += difference_type(unit_bytes); |
|
||||
for(size_type i = 0; i != num_units-1u; ++i, elem += difference_type(unit_bytes)){ |
|
||||
::new (boost::movelib::to_raw_pointer(prev_elem), boost_container_new_t()) void_pointer(elem); |
|
||||
prev_elem = elem; |
|
||||
} |
|
||||
slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); |
|
||||
} |
|
||||
return elem; |
|
||||
} |
|
||||
|
|
||||
void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n) |
|
||||
{ slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); } |
|
||||
|
|
||||
void swap(basic_multiallocation_chain &x) |
|
||||
{ slist_impl_.swap(x.slist_impl_); } |
|
||||
|
|
||||
static iterator iterator_to(const void_pointer &p) |
|
||||
{ return slist_impl_t::s_iterator_to(to_node(p)); } |
|
||||
|
|
||||
pointer_pair extract_data() |
|
||||
{ |
|
||||
if(BOOST_LIKELY(!slist_impl_.empty())){ |
|
||||
pointer_pair ret |
|
||||
(slist_impl_.begin().operator->() |
|
||||
,slist_impl_.last().operator->()); |
|
||||
slist_impl_.clear(); |
|
||||
return ret; |
|
||||
} |
|
||||
else { |
|
||||
return pointer_pair(); |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct cast_functor |
|
||||
{ |
|
||||
typedef typename dtl::add_reference<T>::type result_type; |
|
||||
template<class U> |
|
||||
result_type operator()(U &ptr) const |
|
||||
{ return *static_cast<T*>(static_cast<void*>(&ptr)); } |
|
||||
}; |
|
||||
|
|
||||
template<class MultiallocationChain, class T> |
|
||||
class transform_multiallocation_chain |
|
||||
: public MultiallocationChain |
|
||||
{ |
|
||||
private: |
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain) |
|
||||
//transform_multiallocation_chain(const transform_multiallocation_chain &);
|
|
||||
//transform_multiallocation_chain & operator=(const transform_multiallocation_chain &);
|
|
||||
|
|
||||
typedef typename MultiallocationChain::void_pointer void_pointer; |
|
||||
typedef typename boost::intrusive::pointer_traits |
|
||||
<void_pointer> void_pointer_traits; |
|
||||
typedef typename void_pointer_traits::template |
|
||||
rebind_pointer<T>::type pointer; |
|
||||
typedef typename boost::intrusive::pointer_traits |
|
||||
<pointer> pointer_traits; |
|
||||
|
|
||||
static pointer cast(const void_pointer &p) |
|
||||
{ return pointer_traits::static_cast_from(p); } |
|
||||
|
|
||||
public: |
|
||||
typedef transform_iterator |
|
||||
< typename MultiallocationChain::iterator |
|
||||
, dtl::cast_functor <T> > iterator; |
|
||||
typedef typename MultiallocationChain::size_type size_type; |
|
||||
typedef boost::intrusive::twin<pointer> pointer_pair; |
|
||||
|
|
||||
transform_multiallocation_chain() |
|
||||
: MultiallocationChain() |
|
||||
{} |
|
||||
|
|
||||
transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other) |
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other))) |
|
||||
{} |
|
||||
|
|
||||
transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other) |
|
||||
: MultiallocationChain(::boost::move(static_cast<MultiallocationChain&>(other))) |
|
||||
{} |
|
||||
|
|
||||
transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other) |
|
||||
{ |
|
||||
return static_cast<MultiallocationChain&> |
|
||||
(this->MultiallocationChain::operator=(::boost::move(static_cast<MultiallocationChain&>(other)))); |
|
||||
} |
|
||||
|
|
||||
void push_front(const pointer &mem) |
|
||||
{ this->MultiallocationChain::push_front(mem); } |
|
||||
|
|
||||
void push_back(const pointer &mem) |
|
||||
{ return this->MultiallocationChain::push_back(mem); } |
|
||||
|
|
||||
void swap(transform_multiallocation_chain &other_chain) |
|
||||
{ this->MultiallocationChain::swap(other_chain); } |
|
||||
|
|
||||
void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) |
|
||||
{ this->MultiallocationChain::splice_after(after_this.base(), x, before_b.base(), before_e.base(), n); } |
|
||||
|
|
||||
void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n) |
|
||||
{ this->MultiallocationChain::incorporate_after(after_this.base(), b, before_e, n); } |
|
||||
|
|
||||
pointer pop_front() |
|
||||
{ return cast(this->MultiallocationChain::pop_front()); } |
|
||||
|
|
||||
bool empty() const |
|
||||
{ return this->MultiallocationChain::empty(); } |
|
||||
|
|
||||
iterator before_begin() |
|
||||
{ return iterator(this->MultiallocationChain::before_begin()); } |
|
||||
|
|
||||
iterator begin() |
|
||||
{ return iterator(this->MultiallocationChain::begin()); } |
|
||||
|
|
||||
iterator last() |
|
||||
{ return iterator(this->MultiallocationChain::last()); } |
|
||||
|
|
||||
iterator end() |
|
||||
{ return iterator(this->MultiallocationChain::end()); } |
|
||||
|
|
||||
size_type size() const |
|
||||
{ return this->MultiallocationChain::size(); } |
|
||||
|
|
||||
void clear() |
|
||||
{ this->MultiallocationChain::clear(); } |
|
||||
|
|
||||
iterator insert_after(iterator it, pointer m) |
|
||||
{ return iterator(this->MultiallocationChain::insert_after(it.base(), m)); } |
|
||||
|
|
||||
static iterator iterator_to(const pointer &p) |
|
||||
{ return iterator(MultiallocationChain::iterator_to(p)); } |
|
||||
|
|
||||
pointer_pair extract_data() |
|
||||
{ |
|
||||
typename MultiallocationChain::pointer_pair data(this->MultiallocationChain::extract_data()); |
|
||||
return pointer_pair(cast(data.first), cast(data.second)); |
|
||||
} |
|
||||
/*
|
|
||||
MultiallocationChain &extract_multiallocation_chain() |
|
||||
{ return holder_; }*/ |
|
||||
}; |
|
||||
|
|
||||
}}} |
|
||||
|
|
||||
// namespace dtl {
|
|
||||
// namespace container {
|
|
||||
// namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP
|
|
@ -1,98 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
// container
|
|
||||
#include <boost/container/throw_exception.hpp>
|
|
||||
// container/detail
|
|
||||
#include <boost/container/detail/min_max.hpp>
|
|
||||
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<unsigned Minimum, unsigned Numerator, unsigned Denominator> |
|
||||
struct grow_factor_ratio |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT(Numerator > Denominator); |
|
||||
BOOST_STATIC_ASSERT(Numerator < 100); |
|
||||
BOOST_STATIC_ASSERT(Denominator < 100); |
|
||||
BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator)); |
|
||||
|
|
||||
template<class SizeType> |
|
||||
SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const |
|
||||
{ |
|
||||
const SizeType overflow_limit = ((SizeType)-1) / Numerator; |
|
||||
|
|
||||
SizeType new_cap = 0; |
|
||||
|
|
||||
if(cur_cap <= overflow_limit){ |
|
||||
new_cap = SizeType(cur_cap * Numerator / Denominator); |
|
||||
} |
|
||||
else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){ |
|
||||
new_cap = (SizeType)-1; |
|
||||
} |
|
||||
else{ |
|
||||
new_cap = SizeType(new_cap*Numerator); |
|
||||
} |
|
||||
return max_value<SizeType> |
|
||||
( SizeType(Minimum) |
|
||||
, max_value<SizeType> |
|
||||
( SizeType(cur_cap+add_min_cap) |
|
||||
, min_value<SizeType>(max_cap, new_cap)) |
|
||||
); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
|
|
||||
struct growth_factor_50 |
|
||||
: dtl::grow_factor_ratio<0, 3, 2> |
|
||||
{}; |
|
||||
|
|
||||
struct growth_factor_60 |
|
||||
: dtl::grow_factor_ratio<0, 8, 5> |
|
||||
{}; |
|
||||
|
|
||||
struct growth_factor_100 |
|
||||
: dtl::grow_factor_ratio<0, 2, 1> |
|
||||
{}; |
|
||||
|
|
||||
template<class SizeType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &, SizeType) |
|
||||
{} |
|
||||
|
|
||||
template<class SizeType, class SomeStoredSizeType> |
|
||||
BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &s, SomeStoredSizeType) |
|
||||
{ |
|
||||
if (s >= SomeStoredSizeType(-1) ) |
|
||||
s = SomeStoredSizeType(-1); |
|
||||
} |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP
|
|
@ -1,604 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
|
||||
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
// container
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
// container/detail
|
|
||||
#include <boost/container/detail/addressof.hpp>
|
|
||||
#include <boost/container/detail/alloc_helpers.hpp>
|
|
||||
#include <boost/container/detail/allocator_version_traits.hpp>
|
|
||||
#include <boost/container/detail/construct_in_place.hpp>
|
|
||||
#include <boost/container/detail/destroyers.hpp>
|
|
||||
#include <boost/move/detail/iterator_to_raw_pointer.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/version_type.hpp>
|
|
||||
#include <boost/container/detail/is_pair.hpp>
|
|
||||
// intrusive
|
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
|
||||
#include <boost/intrusive/options.hpp>
|
|
||||
// move
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
//This trait is used to type-pun std::pair because in C++03
|
|
||||
//compilers std::pair is useless for C++11 features
|
|
||||
template<class T, bool> |
|
||||
struct node_internal_data_type |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct node_internal_data_type< T, true> |
|
||||
{ |
|
||||
typedef dtl::pair< typename dtl::remove_const<typename T::first_type>::type |
|
||||
, typename T::second_type> |
|
||||
type; |
|
||||
}; |
|
||||
|
|
||||
template <class T, class HookDefiner, bool PairBased = false> |
|
||||
struct base_node |
|
||||
: public HookDefiner::type |
|
||||
{ |
|
||||
public: |
|
||||
typedef T value_type; |
|
||||
typedef typename node_internal_data_type<T, PairBased && dtl::is_pair<T>::value>::type internal_type; |
|
||||
typedef typename HookDefiner::type hook_type; |
|
||||
|
|
||||
typedef typename dtl::aligned_storage<sizeof(T), dtl::alignment_of<T>::value>::type storage_t; |
|
||||
storage_t m_storage; |
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
|
|
||||
#define BOOST_CONTAINER_DISABLE_ALIASING_WARNING
|
|
||||
# endif
|
|
||||
public: |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class Alloc, class ...Args> |
|
||||
explicit base_node(Alloc &a, Args &&...args) |
|
||||
: hook_type() |
|
||||
{ |
|
||||
::boost::container::allocator_traits<Alloc>::construct |
|
||||
(a, &this->get_real_data(), ::boost::forward<Args>(args)...); |
|
||||
} |
|
||||
|
|
||||
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
#define BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL(N) \
|
|
||||
template< class Alloc BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ |
|
||||
explicit base_node(Alloc &a BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ |
|
||||
: hook_type()\ |
|
||||
{\ |
|
||||
::boost::container::allocator_traits<Alloc>::construct\ |
|
||||
(a, &this->get_real_data() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL) |
|
||||
#undef BOOST_CONTAINER_BASE_NODE_CONSTRUCT_IMPL
|
|
||||
|
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class Alloc, class It> |
|
||||
explicit base_node(iterator_arg_t, Alloc &a, It it) |
|
||||
: hook_type() |
|
||||
{ |
|
||||
::boost::container::construct_in_place(a, &this->get_real_data(), it); |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T &get_data() |
|
||||
{ return *move_detail::force_ptr<T*>(this->m_storage.data); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const T &get_data() const |
|
||||
{ return *move_detail::force_ptr<const T*>(this->m_storage.data); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE internal_type &get_real_data() |
|
||||
{ return *move_detail::force_ptr<internal_type*>(this->m_storage.data); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const internal_type &get_real_data() const |
|
||||
{ return *move_detail::force_ptr<const internal_type*>(this->m_storage.data); } |
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING
|
|
||||
# endif
|
|
||||
|
|
||||
template<class Alloc> |
|
||||
BOOST_CONTAINER_FORCEINLINE void destructor(Alloc &a) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
allocator_traits<Alloc>::destroy |
|
||||
(a, &this->get_real_data()); |
|
||||
this->~base_node(); |
|
||||
} |
|
||||
|
|
||||
template<class Pair> |
|
||||
BOOST_CONTAINER_FORCEINLINE |
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type |
|
||||
do_assign(const Pair &p) |
|
||||
{ |
|
||||
typedef typename Pair::first_type first_type; |
|
||||
const_cast<typename dtl::remove_const<first_type>::type &>(this->get_real_data().first) = p.first; |
|
||||
this->get_real_data().second = p.second; |
|
||||
} |
|
||||
|
|
||||
template<class V> |
|
||||
BOOST_CONTAINER_FORCEINLINE |
|
||||
typename dtl::disable_if< dtl::is_pair<V>, void >::type |
|
||||
do_assign(const V &v) |
|
||||
{ this->get_real_data() = v; } |
|
||||
|
|
||||
template<class Pair> |
|
||||
BOOST_CONTAINER_FORCEINLINE |
|
||||
typename dtl::enable_if< dtl::is_pair<Pair>, void >::type |
|
||||
do_move_assign(Pair &p) |
|
||||
{ |
|
||||
typedef typename Pair::first_type first_type; |
|
||||
const_cast<first_type&>(this->get_real_data().first) = ::boost::move(p.first); |
|
||||
this->get_real_data().second = ::boost::move(p.second); |
|
||||
} |
|
||||
|
|
||||
template<class V> |
|
||||
BOOST_CONTAINER_FORCEINLINE |
|
||||
typename dtl::disable_if< dtl::is_pair<V>, void >::type |
|
||||
do_move_assign(V &v) |
|
||||
{ this->get_real_data() = ::boost::move(v); } |
|
||||
|
|
||||
private: |
|
||||
base_node(); |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~base_node() |
|
||||
{ } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
namespace dtl { |
|
||||
|
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_compare) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(key_equal) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(hasher) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_traits) |
|
||||
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(bucket_type) |
|
||||
|
|
||||
template<class Allocator, class ICont> |
|
||||
struct node_alloc_holder |
|
||||
: public allocator_traits<Allocator>::template |
|
||||
portable_rebind_alloc<typename ICont::value_type>::type //NodeAlloc
|
|
||||
{ |
|
||||
//If the intrusive container is an associative container, obtain the predicate, which will
|
|
||||
//be of type node_compare<>. If not an associative container val_compare will be a "nat" type.
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
( boost::container::dtl:: |
|
||||
, ICont, key_compare, dtl::nat) intrusive_key_compare; |
|
||||
|
|
||||
//If the intrusive container is a hash container, obtain the predicate, which will
|
|
||||
//be of type node_compare<>. If not an associative container val_equal will be a "nat" type.
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, ICont, key_equal, dtl::nat2) intrusive_val_equal; |
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, ICont, hasher, dtl::nat3) intrusive_val_hasher; |
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, ICont, bucket_traits, dtl::natN<0>) intrusive_bucket_traits; |
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, ICont, bucket_type, dtl::natN<1>) intrusive_bucket_type; |
|
||||
//In that case obtain the value predicate from the node predicate via predicate_type
|
|
||||
//if intrusive_key_compare is node_compare<>, nat otherwise
|
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, intrusive_val_equal |
|
||||
, predicate_type, dtl::nat2) val_equal; |
|
||||
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT |
|
||||
(boost::container::dtl:: |
|
||||
, intrusive_val_hasher |
|
||||
, predicate_type, dtl::nat3) val_hasher; |
|
||||
|
|
||||
typedef allocator_traits<Allocator> allocator_traits_type; |
|
||||
typedef typename allocator_traits_type::value_type val_type; |
|
||||
typedef ICont intrusive_container; |
|
||||
typedef typename ICont::value_type Node; |
|
||||
typedef typename allocator_traits_type::template |
|
||||
portable_rebind_alloc<Node>::type NodeAlloc; |
|
||||
typedef allocator_traits<NodeAlloc> node_allocator_traits_type; |
|
||||
typedef dtl::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type; |
|
||||
typedef Allocator ValAlloc; |
|
||||
typedef typename node_allocator_traits_type::pointer NodePtr; |
|
||||
typedef dtl::scoped_deallocator<NodeAlloc> Deallocator; |
|
||||
typedef typename node_allocator_traits_type::size_type size_type; |
|
||||
typedef typename node_allocator_traits_type::difference_type difference_type; |
|
||||
typedef dtl::integral_constant<unsigned, |
|
||||
boost::container::dtl:: |
|
||||
version<NodeAlloc>::value> alloc_version; |
|
||||
typedef typename ICont::iterator icont_iterator; |
|
||||
typedef typename ICont::const_iterator icont_citerator; |
|
||||
typedef allocator_node_destroyer<NodeAlloc> Destroyer; |
|
||||
typedef allocator_traits<NodeAlloc> NodeAllocTraits; |
|
||||
typedef allocator_version_traits<NodeAlloc> AllocVersionTraits; |
|
||||
|
|
||||
private: |
|
||||
BOOST_COPYABLE_AND_MOVABLE(node_alloc_holder) |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
//Constructors for sequence containers
|
|
||||
BOOST_CONTAINER_FORCEINLINE node_alloc_holder() |
|
||||
{} |
|
||||
|
|
||||
explicit node_alloc_holder(const intrusive_bucket_traits& bt) |
|
||||
: m_icont(bt) |
|
||||
{} |
|
||||
|
|
||||
explicit node_alloc_holder(const ValAlloc &a) |
|
||||
: NodeAlloc(a) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const intrusive_bucket_traits& bt, const ValAlloc& a) |
|
||||
: NodeAlloc(a) |
|
||||
, m_icont(bt) |
|
||||
{} |
|
||||
|
|
||||
//Constructors for associative containers
|
|
||||
node_alloc_holder(const intrusive_key_compare &c, const ValAlloc &a) |
|
||||
: NodeAlloc(a), m_icont(c) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const intrusive_bucket_traits & bt, const val_hasher &hf, const val_equal &eql, const ValAlloc &a) |
|
||||
: NodeAlloc(a) |
|
||||
, m_icont(bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal(eql)) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf, const ValAlloc &a) |
|
||||
: NodeAlloc(a) |
|
||||
, m_icont(bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal()) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const intrusive_bucket_traits& bt, const val_hasher &hf) |
|
||||
: m_icont(bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal()) |
|
||||
{} |
|
||||
|
|
||||
explicit node_alloc_holder(const node_alloc_holder &x) |
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const node_alloc_holder &x, const intrusive_key_compare &c) |
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) |
|
||||
, m_icont(c) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const node_alloc_holder &x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql) |
|
||||
: NodeAlloc(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc())) |
|
||||
, m_icont( bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal(eql)) |
|
||||
{} |
|
||||
|
|
||||
node_alloc_holder(const val_hasher &hf, const intrusive_bucket_traits& bt, const val_equal &eql) |
|
||||
: m_icont(bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal(eql)) |
|
||||
{} |
|
||||
|
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x) |
|
||||
: NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())) |
|
||||
{ this->icont().swap(x.icont()); } |
|
||||
|
|
||||
explicit node_alloc_holder(const intrusive_key_compare &c) |
|
||||
: m_icont(c) |
|
||||
{} |
|
||||
|
|
||||
//helpers for move assignments
|
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_key_compare &c) |
|
||||
: NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())), m_icont(c) |
|
||||
{ this->icont().swap(x.icont()); } |
|
||||
|
|
||||
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const intrusive_bucket_traits& bt, const val_hasher &hf, const val_equal &eql) |
|
||||
: NodeAlloc(boost::move(BOOST_MOVE_TO_LV(x).node_alloc())) |
|
||||
, m_icont( bt |
|
||||
, typename ICont::hasher(hf) |
|
||||
, typename ICont::key_equal(eql)) |
|
||||
{ this->icont().swap(BOOST_MOVE_TO_LV(x).icont()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void copy_assign_alloc(const node_alloc_holder &x) |
|
||||
{ |
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_copy_assignment::value> flag; |
|
||||
dtl::assign_alloc( static_cast<NodeAlloc &>(*this) |
|
||||
, static_cast<const NodeAlloc &>(x), flag); |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void move_assign_alloc( node_alloc_holder &x) |
|
||||
{ |
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_move_assignment::value> flag; |
|
||||
dtl::move_alloc( static_cast<NodeAlloc &>(*this) |
|
||||
, static_cast<NodeAlloc &>(x), flag); |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ~node_alloc_holder() |
|
||||
{ this->clear(alloc_version()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE size_type max_size() const |
|
||||
{ return allocator_traits_type::max_size(this->node_alloc()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE NodePtr allocate_one() |
|
||||
{ return AllocVersionTraits::allocate_one(this->node_alloc()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void deallocate_one(const NodePtr &p) |
|
||||
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); } |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class ...Args> |
|
||||
NodePtr create_node(Args &&...args) |
|
||||
{ |
|
||||
NodePtr p = this->allocate_one(); |
|
||||
NodeAlloc &nalloc = this->node_alloc(); |
|
||||
Deallocator node_deallocator(p, nalloc); |
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) |
|
||||
Node(nalloc, boost::forward<Args>(args)...); |
|
||||
node_deallocator.release(); |
|
||||
return (p); |
|
||||
} |
|
||||
|
|
||||
#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
#define BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL(N) \
|
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ |
|
||||
NodePtr create_node(BOOST_MOVE_UREF##N)\ |
|
||||
{\ |
|
||||
NodePtr p = this->allocate_one();\ |
|
||||
NodeAlloc &nalloc = this->node_alloc();\ |
|
||||
Deallocator node_deallocator(p, nalloc);\ |
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t())\ |
|
||||
Node(nalloc BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ |
|
||||
node_deallocator.release();\ |
|
||||
return (p);\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL) |
|
||||
#undef BOOST_CONTAINER_NODE_ALLOC_HOLDER_CONSTRUCT_IMPL
|
|
||||
|
|
||||
#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
|
|
||||
template<class It> |
|
||||
NodePtr create_node_from_it(const It &it) |
|
||||
{ |
|
||||
NodePtr p = this->allocate_one(); |
|
||||
NodeAlloc &nalloc = this->node_alloc(); |
|
||||
Deallocator node_deallocator(p, nalloc); |
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) |
|
||||
Node(iterator_arg_t(), nalloc, it); |
|
||||
node_deallocator.release(); |
|
||||
return (p); |
|
||||
} |
|
||||
|
|
||||
template<class KeyConvertible> |
|
||||
NodePtr create_node_from_key(BOOST_FWD_REF(KeyConvertible) key) |
|
||||
{ |
|
||||
NodePtr p = this->allocate_one(); |
|
||||
BOOST_CONTAINER_TRY{ |
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) Node; |
|
||||
NodeAlloc &na = this->node_alloc(); |
|
||||
node_allocator_traits_type::construct |
|
||||
(na, dtl::addressof(p->get_real_data().first), boost::forward<KeyConvertible>(key)); |
|
||||
BOOST_CONTAINER_TRY{ |
|
||||
node_allocator_traits_type::construct(na, dtl::addressof(p->get_real_data().second)); |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH(...){ |
|
||||
node_allocator_traits_type::destroy(na, dtl::addressof(p->get_real_data().first)); |
|
||||
BOOST_CONTAINER_RETHROW; |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH_END |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH(...) { |
|
||||
p->destroy_header(); |
|
||||
this->node_alloc().deallocate(p, 1); |
|
||||
BOOST_CONTAINER_RETHROW |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH_END |
|
||||
return (p); |
|
||||
} |
|
||||
|
|
||||
void destroy_node(const NodePtr &nodep) |
|
||||
{ |
|
||||
boost::movelib::to_raw_pointer(nodep)->destructor(this->node_alloc()); |
|
||||
this->deallocate_one(nodep); |
|
||||
} |
|
||||
|
|
||||
void swap(node_alloc_holder &x) |
|
||||
{ |
|
||||
this->icont().swap(x.icont()); |
|
||||
dtl::bool_<allocator_traits_type::propagate_on_container_swap::value> flag; |
|
||||
dtl::swap_alloc(this->node_alloc(), x.node_alloc(), flag); |
|
||||
} |
|
||||
|
|
||||
template<class FwdIterator, class Inserter> |
|
||||
void allocate_many_and_construct |
|
||||
(FwdIterator beg, size_type n, Inserter inserter) |
|
||||
{ |
|
||||
if(n){ |
|
||||
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain_t; |
|
||||
|
|
||||
//Try to allocate memory in a single block
|
|
||||
typedef typename multiallocation_chain_t::iterator multialloc_iterator_t; |
|
||||
multiallocation_chain_t chain; |
|
||||
NodeAlloc &nalloc = this->node_alloc(); |
|
||||
node_allocator_version_traits_type::allocate_individual(nalloc, n, chain); |
|
||||
multialloc_iterator_t itbeg = chain.begin(); |
|
||||
multialloc_iterator_t itlast = chain.last(); |
|
||||
chain.clear(); |
|
||||
|
|
||||
Node *p = 0; |
|
||||
BOOST_CONTAINER_TRY{ |
|
||||
Deallocator node_deallocator(NodePtr(), nalloc); |
|
||||
dtl::scoped_node_destructor<NodeAlloc> sdestructor(nalloc, 0); |
|
||||
while(n){ |
|
||||
--n; |
|
||||
p = boost::movelib::iterator_to_raw_pointer(itbeg); |
|
||||
++itbeg; //Increment iterator before overwriting pointed memory
|
|
||||
//This does not throw
|
|
||||
::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) |
|
||||
Node(iterator_arg_t(), nalloc, beg); |
|
||||
sdestructor.set(p); |
|
||||
++beg; |
|
||||
//This can throw in some containers (predicate might throw).
|
|
||||
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
|
|
||||
inserter(*p); |
|
||||
sdestructor.release(); |
|
||||
} |
|
||||
sdestructor.release(); |
|
||||
node_deallocator.release(); |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH(...){ |
|
||||
chain.incorporate_after(chain.last(), &*itbeg, &*itlast, n); |
|
||||
node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), chain); |
|
||||
BOOST_CONTAINER_RETHROW |
|
||||
} |
|
||||
BOOST_CONTAINER_CATCH_END |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void clear(version_1) |
|
||||
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); } |
|
||||
|
|
||||
void clear(version_2) |
|
||||
{ |
|
||||
typename NodeAlloc::multiallocation_chain chain; |
|
||||
allocator_node_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain); |
|
||||
this->icont().clear_and_dispose(builder); |
|
||||
//BOOST_STATIC_ASSERT((::boost::has_move_emulation_enabled<typename NodeAlloc::multiallocation_chain>::value == true));
|
|
||||
if(!chain.empty()) |
|
||||
this->node_alloc().deallocate_individual(chain); |
|
||||
} |
|
||||
|
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1) |
|
||||
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); } |
|
||||
|
|
||||
icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2) |
|
||||
{ |
|
||||
NodeAlloc & nalloc = this->node_alloc(); |
|
||||
typename NodeAlloc::multiallocation_chain chain; |
|
||||
allocator_node_destroyer_and_chain_builder<NodeAlloc> chain_builder(nalloc, chain); |
|
||||
icont_iterator ret_it = this->icont().erase_and_dispose(first, last, chain_builder); |
|
||||
nalloc.deallocate_individual(chain); |
|
||||
return ret_it; |
|
||||
} |
|
||||
|
|
||||
template<class Key> |
|
||||
BOOST_CONTAINER_FORCEINLINE size_type erase_key(const Key& k, version_1) |
|
||||
{ return this->icont().erase_and_dispose(k, Destroyer(this->node_alloc())); } |
|
||||
|
|
||||
template<class Key> |
|
||||
BOOST_CONTAINER_FORCEINLINE size_type erase_key(const Key& k, version_2) |
|
||||
{ |
|
||||
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc()); |
|
||||
return this->icont().erase_and_dispose(k, chain_holder.get_chain_builder()); |
|
||||
} |
|
||||
|
|
||||
protected: |
|
||||
struct cloner |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit cloner(node_alloc_holder &holder) |
|
||||
: m_holder(holder) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE NodePtr operator()(const Node &other) const |
|
||||
{ return m_holder.create_node(other.get_real_data()); } |
|
||||
|
|
||||
node_alloc_holder &m_holder; |
|
||||
}; |
|
||||
|
|
||||
struct move_cloner |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE move_cloner(node_alloc_holder &holder) |
|
||||
: m_holder(holder) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE NodePtr operator()(Node &other) |
|
||||
{ //Use get_real_data() instead of get_real_data to allow moving const key in [multi]map
|
|
||||
return m_holder.create_node(::boost::move(other.get_real_data())); |
|
||||
} |
|
||||
|
|
||||
node_alloc_holder &m_holder; |
|
||||
}; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE ICont &non_const_icont() const |
|
||||
{ return const_cast<ICont&>(this->m_icont); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE NodeAlloc &node_alloc() |
|
||||
{ return static_cast<NodeAlloc &>(*this); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const NodeAlloc &node_alloc() const |
|
||||
{ return static_cast<const NodeAlloc &>(*this); } |
|
||||
|
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE ICont &icont() |
|
||||
{ return this->m_icont; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const ICont &icont() const |
|
||||
{ return this->m_icont; } |
|
||||
|
|
||||
protected: |
|
||||
//The intrusive container
|
|
||||
ICont m_icont; |
|
||||
}; |
|
||||
|
|
||||
template<class Node, class KeyOfValue> |
|
||||
struct key_of_node : KeyOfValue |
|
||||
{ |
|
||||
typedef typename KeyOfValue::type type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE key_of_node() |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const type& operator()(const Node& x) const |
|
||||
{ return this->KeyOfValue::operator()(x.get_data()); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
|
|
@ -1,607 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
|
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/container_fwd.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/std_fwd.hpp>
|
|
||||
#include <boost/container/detail/is_pair.hpp>
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
# include <boost/container/detail/variadic_templates_tools.hpp>
|
|
||||
#endif
|
|
||||
#include <boost/move/adl_move_swap.hpp> //swap
|
|
||||
|
|
||||
#include <boost/intrusive/detail/minimal_pair_header.hpp> //pair
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/move/detail/fwd_macros.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace pair_impl { |
|
||||
|
|
||||
template <class TupleClass> |
|
||||
struct is_boost_tuple |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template < |
|
||||
class T0, class T1, class T2, |
|
||||
class T3, class T4, class T5, |
|
||||
class T6, class T7, class T8, |
|
||||
class T9> |
|
||||
struct is_boost_tuple< boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template<class Tuple> |
|
||||
struct disable_if_boost_tuple |
|
||||
: boost::container::dtl::disable_if< is_boost_tuple<Tuple> > |
|
||||
{}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_tuple_null |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<> |
|
||||
struct is_tuple_null<boost::tuples::null_type> |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
} //namespace detail {
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
template <int Dummy = 0> |
|
||||
struct std_piecewise_construct_holder |
|
||||
{ |
|
||||
static ::std::piecewise_construct_t *dummy; |
|
||||
}; |
|
||||
|
|
||||
template <int Dummy> |
|
||||
::std::piecewise_construct_t *std_piecewise_construct_holder<Dummy>::dummy = |
|
||||
reinterpret_cast< ::std::piecewise_construct_t *>(0x01234); //Avoid sanitizer errors on references to null pointers
|
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
//! The piecewise_construct_t struct is an empty structure type used as a unique type to
|
|
||||
//! disambiguate used to disambiguate between different functions that take two tuple arguments.
|
|
||||
typedef unspecified piecewise_construct_t; |
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//! A instance of type
|
|
||||
//! piecewise_construct_t
|
|
||||
static piecewise_construct_t piecewise_construct = BOOST_CONTAINER_DOC1ST(unspecified, *std_piecewise_construct_holder<>::dummy); |
|
||||
|
|
||||
///@cond
|
|
||||
|
|
||||
namespace dtl { |
|
||||
|
|
||||
struct piecewise_construct_use |
|
||||
{ |
|
||||
//Avoid warnings of unused "piecewise_construct"
|
|
||||
piecewise_construct_use() |
|
||||
{ (void)&::boost::container::piecewise_construct; } |
|
||||
}; |
|
||||
|
|
||||
struct pair_nat; |
|
||||
|
|
||||
template<typename T, typename U, typename V> |
|
||||
void get(T); //to enable ADL
|
|
||||
|
|
||||
///@endcond
|
|
||||
|
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
|
|
||||
//Libc++, in some versions, has an ABI breakage that needs some
|
|
||||
//padding in dtl::pair, as "std::pair::first" is not at offset zero.
|
|
||||
//See: https://reviews.llvm.org/D56357 for more information.
|
|
||||
//
|
|
||||
template <class T1, class T2, std::size_t N> |
|
||||
struct pair_padding |
|
||||
{ |
|
||||
char padding[N]; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct pair_padding<T1, T2, 0> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct simple_pair |
|
||||
{ |
|
||||
T1 first; |
|
||||
T2 second; |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct pair |
|
||||
#ifdef _LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR
|
|
||||
: pair_padding<T1, T2, sizeof(std::pair<T1, T2>) - sizeof(simple_pair<T1, T2>)> |
|
||||
#endif
|
|
||||
{ |
|
||||
private: |
|
||||
BOOST_COPYABLE_AND_MOVABLE(pair) |
|
||||
|
|
||||
public: |
|
||||
typedef T1 first_type; |
|
||||
typedef T2 second_type; |
|
||||
|
|
||||
T1 first; |
|
||||
T2 second; |
|
||||
|
|
||||
//Default constructor
|
|
||||
pair() |
|
||||
: first(), second() |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
//pair copy assignment
|
|
||||
pair(const pair& x) |
|
||||
: first(x.first), second(x.second) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
//pair move constructor
|
|
||||
pair(BOOST_RV_REF(pair) p) |
|
||||
: first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair(const pair<D, S> &p) |
|
||||
: first(p.first), second(p.second) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p) |
|
||||
: first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
//pair from two values
|
|
||||
pair(const T1 &t1, const T2 &t2) |
|
||||
: first(t1) |
|
||||
, second(t2) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
template<class U, class V> |
|
||||
pair(BOOST_FWD_REF(U) u, BOOST_FWD_REF(V) v) |
|
||||
: first(::boost::forward<U>(u)) |
|
||||
, second(::boost::forward<V>(v)) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
//And now compatibility with std::pair
|
|
||||
pair(const std::pair<T1, T2>& x) |
|
||||
: first(x.first), second(x.second) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair(const std::pair<D, S>& p) |
|
||||
: first(p.first), second(p.second) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
pair(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p) |
|
||||
: first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p) |
|
||||
: first(::boost::move(BOOST_MOVE_TO_LV(p).first)), second(::boost::move(BOOST_MOVE_TO_LV(p).second)) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
template< class KeyType, class ...Args> |
|
||||
pair(try_emplace_t, BOOST_FWD_REF(KeyType) k, Args && ...args) |
|
||||
: first(boost::forward<KeyType>(k)), second(::boost::forward<Args>(args)...)\ |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
#else
|
|
||||
|
|
||||
//piecewise construction from boost::tuple
|
|
||||
#define BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE(N)\
|
|
||||
template< class KeyType BOOST_MOVE_I##N BOOST_MOVE_CLASS##N > \ |
|
||||
pair( try_emplace_t, BOOST_FWD_REF(KeyType) k BOOST_MOVE_I##N BOOST_MOVE_UREF##N )\ |
|
||||
: first(boost::forward<KeyType>(k)), second(BOOST_MOVE_FWD##N)\ |
|
||||
{\ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE) |
|
||||
#undef BOOST_PAIR_TRY_EMPLACE_CONSTRUCT_CODE
|
|
||||
|
|
||||
#endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
|
||||
|
|
||||
//piecewise construction from boost::tuple
|
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE(N,M)\
|
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class BoostTuple \ |
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ |
|
||||
pair( piecewise_construct_t\ |
|
||||
, BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> p\ |
|
||||
, BoostTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::boost::tuples::null_type)> q\ |
|
||||
, typename dtl::enable_if_c\ |
|
||||
< pair_impl::is_boost_tuple< BoostTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::boost::tuples::null_type)> >::value &&\ |
|
||||
!(pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARG##N>::value || pair_impl::is_tuple_null<BOOST_MOVE_LAST_TARGQ##M>::value) \ |
|
||||
>::type* = 0\ |
|
||||
)\ |
|
||||
: first(BOOST_MOVE_TMPL_GET##N), second(BOOST_MOVE_TMPL_GETQ##M)\ |
|
||||
{ (void)p; (void)q;\ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE) |
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_BOOST_TUPLE_CODE
|
|
||||
|
|
||||
//piecewise construction from variadic tuple (with delegating constructors)
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||
# if !defined(BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS)
|
|
||||
private: |
|
||||
template<template<class ...> class Tuple, class... Args1, class... Args2, size_t... Indexes1, size_t... Indexes2> |
|
||||
pair(Tuple<Args1...>& t1, Tuple<Args2...>& t2, index_tuple<Indexes1...>, index_tuple<Indexes2...>) |
|
||||
: first (::boost::forward<Args1>(get<Indexes1>(t1))...) |
|
||||
, second(::boost::forward<Args2>(get<Indexes2>(t2))...) |
|
||||
{ (void) t1; (void)t2; } |
|
||||
|
|
||||
public: |
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2 |
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type> |
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) |
|
||||
: pair(t1, t2, typename build_number_seq<sizeof...(Args1)>::type(), typename build_number_seq<sizeof...(Args2)>::type()) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
# else
|
|
||||
//piecewise construction from variadic tuple (suboptimal, without delegating constructors)
|
|
||||
private: |
|
||||
template<typename T, template<class ...> class Tuple, typename... Args> |
|
||||
static T build_from_args(Tuple<Args...>&& t) |
|
||||
{ return do_build_from_args<T>(::boost::move(t), typename build_number_seq<sizeof...(Args)>::type()); } |
|
||||
|
|
||||
template<typename T, template<class ...> class Tuple, typename... Args, std::size_t... Indexes> |
|
||||
static T do_build_from_args(Tuple<Args...> && t, const index_tuple<Indexes...>&) |
|
||||
{ (void)t; return T(::boost::forward<Args>(get<Indexes>(t))...); } |
|
||||
|
|
||||
public: |
|
||||
template< template<class ...> class Tuple, class... Args1, class... Args2 |
|
||||
, class = typename pair_impl::disable_if_boost_tuple< Tuple<Args1...> >::type> |
|
||||
pair(piecewise_construct_t, Tuple<Args1...> t1, Tuple<Args2...> t2) |
|
||||
: first (build_from_args<first_type> (::boost::move(t1))) |
|
||||
, second (build_from_args<second_type>(::boost::move(t2))) |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>))); |
|
||||
} |
|
||||
# endif //BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 520)
|
|
||||
//MSVC 2010 tuple implementation
|
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE(N,M)\
|
|
||||
template< template<class, class, class, class, class, class, class, class, class, class> class StdTuple \ |
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ |
|
||||
pair( piecewise_construct_t\ |
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,N),::std::tr1::_Nil)> p\ |
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(10,M),::std::tr1::_Nil)> q)\ |
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ |
|
||||
{ (void)p; (void)q;\ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITER2D_0TOMAX(9, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE) |
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
|
||||
#elif defined(BOOST_MSVC) && (_CPPLIB_VER == 540)
|
|
||||
#if _VARIADIC_MAX >= 9
|
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT 9
|
|
||||
#else
|
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT BOOST_MOVE_ADD(_VARIADIC_MAX, 1)
|
|
||||
#endif
|
|
||||
|
|
||||
//MSVC 2012 tuple implementation
|
|
||||
#define BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE(N,M)\
|
|
||||
template< template<BOOST_MOVE_REPEAT(_VARIADIC_MAX, class), class, class, class> class StdTuple \ |
|
||||
BOOST_MOVE_I_IF(BOOST_MOVE_OR(N,M)) BOOST_MOVE_CLASS##N BOOST_MOVE_I_IF(BOOST_MOVE_AND(N,M)) BOOST_MOVE_CLASSQ##M > \ |
|
||||
pair( piecewise_construct_t\ |
|
||||
, StdTuple<BOOST_MOVE_TARG##N BOOST_MOVE_I##N BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),N),::std::_Nil) > p\ |
|
||||
, StdTuple<BOOST_MOVE_TARGQ##M BOOST_MOVE_I##M BOOST_MOVE_REPEAT(BOOST_MOVE_SUB(BOOST_MOVE_ADD(_VARIADIC_MAX, 3),M),::std::_Nil) > q)\ |
|
||||
: first(BOOST_MOVE_GET_IDX##N), second(BOOST_MOVE_GET_IDXQ##M)\ |
|
||||
{ (void)p; (void)q;\ |
|
||||
BOOST_STATIC_ASSERT((sizeof(std::pair<T1, T2>) == sizeof(pair<T1, T2>)));\ |
|
||||
}\ |
|
||||
//
|
|
||||
BOOST_MOVE_ITER2D_0TOMAX(BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT, BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_CODE) |
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2010_TUPLE_CODE
|
|
||||
#undef BOOST_PAIR_PIECEWISE_CONSTRUCT_MSVC2012_TUPLE_MAX_IT
|
|
||||
#endif
|
|
||||
|
|
||||
//pair copy assignment
|
|
||||
pair& operator=(BOOST_COPY_ASSIGN_REF(pair) p) |
|
||||
{ |
|
||||
first = p.first; |
|
||||
second = p.second; |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//pair move assignment
|
|
||||
pair& operator=(BOOST_RV_REF(pair) p) |
|
||||
{ |
|
||||
first = ::boost::move(BOOST_MOVE_TO_LV(p).first); |
|
||||
second = ::boost::move(BOOST_MOVE_TO_LV(p).second); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
typename ::boost::container::dtl::disable_if_or |
|
||||
< pair & |
|
||||
, ::boost::container::dtl::is_same<T1, D> |
|
||||
, ::boost::container::dtl::is_same<T2, S> |
|
||||
>::type |
|
||||
operator=(const pair<D, S>&p) |
|
||||
{ |
|
||||
first = p.first; |
|
||||
second = p.second; |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
typename ::boost::container::dtl::disable_if_or |
|
||||
< pair & |
|
||||
, ::boost::container::dtl::is_same<T1, D> |
|
||||
, ::boost::container::dtl::is_same<T2, S> |
|
||||
>::type |
|
||||
operator=(BOOST_RV_REF_BEG pair<D, S> BOOST_RV_REF_END p) |
|
||||
{ |
|
||||
first = ::boost::move(BOOST_MOVE_TO_LV(p).first); |
|
||||
second = ::boost::move(BOOST_MOVE_TO_LV(p).second); |
|
||||
return *this; |
|
||||
} |
|
||||
//std::pair copy assignment
|
|
||||
pair& operator=(const std::pair<T1, T2> &p) |
|
||||
{ |
|
||||
first = p.first; |
|
||||
second = p.second; |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair& operator=(const std::pair<D, S> &p) |
|
||||
{ |
|
||||
first = ::boost::move(p.first); |
|
||||
second = ::boost::move(p.second); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//std::pair move assignment
|
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<T1, T2> BOOST_RV_REF_END p) |
|
||||
{ |
|
||||
first = ::boost::move(BOOST_MOVE_TO_LV(p).first); |
|
||||
second = ::boost::move(BOOST_MOVE_TO_LV(p).second); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <class D, class S> |
|
||||
pair& operator=(BOOST_RV_REF_BEG std::pair<D, S> BOOST_RV_REF_END p) |
|
||||
{ |
|
||||
first = ::boost::move(BOOST_MOVE_TO_LV(p).first); |
|
||||
second = ::boost::move(BOOST_MOVE_TO_LV(p).second); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//swap
|
|
||||
void swap(pair& p) |
|
||||
{ |
|
||||
::boost::adl_move_swap(this->first, p.first); |
|
||||
::boost::adl_move_swap(this->second, p.second); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator==(const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return static_cast<bool>(x.first == y.first && x.second == y.second); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator< (const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return static_cast<bool>(x.first < y.first || |
|
||||
(!(y.first < x.first) && x.second < y.second)); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator!=(const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return static_cast<bool>(!(x == y)); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator> (const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return y < x; } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator>=(const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return static_cast<bool>(!(x < y)); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline bool operator<=(const pair<T1,T2>& x, const pair<T1,T2>& y) |
|
||||
{ return static_cast<bool>(!(y < x)); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline pair<T1, T2> make_pair(T1 x, T2 y) |
|
||||
{ return pair<T1, T2>(x, y); } |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y) |
|
||||
{ x.swap(y); } |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
|
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
|
||||
|
|
||||
template<class T1, class T2> |
|
||||
struct has_move_emulation_enabled< ::boost::container::dtl::pair<T1, T2> > |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
namespace move_detail{ |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_class_or_union; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_class_or_union< ::boost::container::dtl::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_class_or_union< std::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_union; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_union< ::boost::container::dtl::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_union< std::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_class; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_class< ::boost::container::dtl::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
template <class T1, class T2> |
|
||||
struct is_class< std::pair<T1, T2> > |
|
||||
//This specialization is needed to avoid instantiation of pair in
|
|
||||
//is_class, and allow recursive maps.
|
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
//Triviality of pair
|
|
||||
template<class T> |
|
||||
struct is_trivially_copy_constructible; |
|
||||
|
|
||||
template<class A, class B> |
|
||||
struct is_trivially_copy_assignable |
|
||||
<boost::container::dtl::pair<A,B> > |
|
||||
{ |
|
||||
static const bool value = false ; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_trivially_move_constructible; |
|
||||
|
|
||||
template<class A, class B> |
|
||||
struct is_trivially_move_assignable |
|
||||
<boost::container::dtl::pair<A,B> > |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_trivially_copy_assignable; |
|
||||
|
|
||||
template<class A, class B> |
|
||||
struct is_trivially_copy_constructible<boost::container::dtl::pair<A,B> > |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_trivially_move_assignable; |
|
||||
|
|
||||
template<class A, class B> |
|
||||
struct is_trivially_move_constructible<boost::container::dtl::pair<A,B> > |
|
||||
{ |
|
||||
static const bool value = false; |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct is_trivially_destructible; |
|
||||
|
|
||||
template<class A, class B> |
|
||||
struct is_trivially_destructible<boost::container::dtl::pair<A,B> > |
|
||||
{ |
|
||||
static const bool value = boost::move_detail::is_trivially_destructible<A>::value && |
|
||||
boost::move_detail::is_trivially_destructible<B>::value ; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
} //namespace move_detail{
|
|
||||
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_PAIR_HPP
|
|
@ -1,55 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
|
||||
#define BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
template<class Key, class Mapped> |
|
||||
struct pair_key_mapped_of_value |
|
||||
{ |
|
||||
typedef Key key_type; |
|
||||
typedef Mapped mapped_type; |
|
||||
|
|
||||
template<class Pair> |
|
||||
const key_type & key_of_value(const Pair &p) const |
|
||||
{ return p.first; } |
|
||||
|
|
||||
template<class Pair> |
|
||||
const mapped_type & mapped_of_value(const Pair &p) const |
|
||||
{ return p.second; } |
|
||||
|
|
||||
template<class Pair> |
|
||||
key_type & key_of_value(Pair &p) const |
|
||||
{ return const_cast<key_type&>(p.first); } |
|
||||
|
|
||||
template<class Pair> |
|
||||
mapped_type & mapped_of_value(Pair &p) const |
|
||||
{ return p.second; } |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
}} |
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // BOOST_CONTAINER_PAIR_KEY_MAPPED_OF_VALUE_HPP
|
|
@ -1,24 +0,0 @@ |
|||||
#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#include <cstddef>
|
|
||||
|
|
||||
struct boost_container_new_t{}; |
|
||||
|
|
||||
//avoid including <new>
|
|
||||
inline void *operator new(std::size_t, void *p, boost_container_new_t) |
|
||||
{ return p; } |
|
||||
|
|
||||
inline void operator delete(void *, void *, boost_container_new_t) |
|
||||
{} |
|
||||
|
|
||||
#endif //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP
|
|
@ -1,62 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
// Standard predeclarations
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#include <boost/move/detail/std_ns_begin.hpp>
|
|
||||
BOOST_MOVE_STD_NS_BEG |
|
||||
|
|
||||
template<class T> |
|
||||
class allocator; |
|
||||
|
|
||||
template<class T> |
|
||||
struct less; |
|
||||
|
|
||||
template<class T> |
|
||||
struct equal_to; |
|
||||
|
|
||||
template<class T1, class T2> |
|
||||
struct pair; |
|
||||
|
|
||||
template<class T> |
|
||||
struct char_traits; |
|
||||
|
|
||||
struct input_iterator_tag; |
|
||||
struct forward_iterator_tag; |
|
||||
struct bidirectional_iterator_tag; |
|
||||
struct random_access_iterator_tag; |
|
||||
|
|
||||
template<class Container> |
|
||||
class insert_iterator; |
|
||||
|
|
||||
struct allocator_arg_t; |
|
||||
|
|
||||
struct piecewise_construct_t; |
|
||||
|
|
||||
template <class Ptr> |
|
||||
struct pointer_traits; |
|
||||
|
|
||||
BOOST_MOVE_STD_NS_END |
|
||||
#include <boost/move/detail/std_ns_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP
|
|
@ -1,180 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
// (C) Copyright Gennaro Prota 2003 - 2004.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/iterator.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
template <class PseudoReference> |
|
||||
struct operator_arrow_proxy |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(const PseudoReference &px) |
|
||||
: m_value(px) |
|
||||
{} |
|
||||
|
|
||||
typedef PseudoReference element_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE PseudoReference* operator->() const { return &m_value; } |
|
||||
|
|
||||
mutable PseudoReference m_value; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct operator_arrow_proxy<T&> |
|
||||
{ |
|
||||
BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy(T &px) |
|
||||
: m_value(px) |
|
||||
{} |
|
||||
|
|
||||
typedef T element_type; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE T* operator->() const { return const_cast<T*>(&m_value); } |
|
||||
|
|
||||
T &m_value; |
|
||||
}; |
|
||||
|
|
||||
template <class Iterator, class UnaryFunction> |
|
||||
class transform_iterator |
|
||||
: public UnaryFunction |
|
||||
, public boost::container::iterator |
|
||||
< typename Iterator::iterator_category |
|
||||
, typename dtl::remove_reference<typename UnaryFunction::result_type>::type |
|
||||
, typename Iterator::difference_type |
|
||||
, operator_arrow_proxy<typename UnaryFunction::result_type> |
|
||||
, typename UnaryFunction::result_type> |
|
||||
{ |
|
||||
public: |
|
||||
BOOST_CONTAINER_FORCEINLINE explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) |
|
||||
: UnaryFunction(f), m_it(it) |
|
||||
{} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit transform_iterator() |
|
||||
: UnaryFunction(), m_it() |
|
||||
{} |
|
||||
|
|
||||
//Constructors
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator& operator++() |
|
||||
{ increment(); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator operator++(int) |
|
||||
{ |
|
||||
transform_iterator result (*this); |
|
||||
increment(); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator== (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return i.equal(i2); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return !(i == i2); } |
|
||||
|
|
||||
/*
|
|
||||
friend bool operator> (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return i2 < i; } |
|
||||
|
|
||||
friend bool operator<= (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return !(i > i2); } |
|
||||
|
|
||||
friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return !(i < i2); } |
|
||||
*/ |
|
||||
BOOST_CONTAINER_FORCEINLINE friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) |
|
||||
{ return i2.distance_to(i); } |
|
||||
|
|
||||
//Arithmetic
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator& operator+=(typename Iterator::difference_type off) |
|
||||
{ this->advance(off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator operator+(typename Iterator::difference_type off) const |
|
||||
{ |
|
||||
transform_iterator other(*this); |
|
||||
other.advance(off); |
|
||||
return other; |
|
||||
} |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) |
|
||||
{ return right + off; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator& operator-=(typename Iterator::difference_type off) |
|
||||
{ this->advance(-off); return *this; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator operator-(typename Iterator::difference_type off) const |
|
||||
{ return *this + (-off); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type operator*() const |
|
||||
{ return dereference(); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE operator_arrow_proxy<typename UnaryFunction::result_type> |
|
||||
operator->() const |
|
||||
{ return operator_arrow_proxy<typename UnaryFunction::result_type>(dereference()); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE Iterator & base() |
|
||||
{ return m_it; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE const Iterator & base() const |
|
||||
{ return m_it; } |
|
||||
|
|
||||
private: |
|
||||
Iterator m_it; |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void increment() |
|
||||
{ ++m_it; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void decrement() |
|
||||
{ --m_it; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool equal(const transform_iterator &other) const |
|
||||
{ return m_it == other.m_it; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE bool less(const transform_iterator &other) const |
|
||||
{ return other.m_it < m_it; } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE typename UnaryFunction::result_type dereference() const |
|
||||
{ return UnaryFunction::operator()(*m_it); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE void advance(typename Iterator::difference_type n) |
|
||||
{ boost::container::iterator_advance(m_it, n); } |
|
||||
|
|
||||
BOOST_CONTAINER_FORCEINLINE typename Iterator::difference_type distance_to(const transform_iterator &other)const |
|
||||
{ return boost::container::iterator_distance(other.m_it, m_it); } |
|
||||
}; |
|
||||
|
|
||||
template <class Iterator, class UnaryFunc> |
|
||||
BOOST_CONTAINER_FORCEINLINE transform_iterator<Iterator, UnaryFunc> |
|
||||
make_transform_iterator(Iterator it, UnaryFunc fun) |
|
||||
{ |
|
||||
return transform_iterator<Iterator, UnaryFunc>(it, fun); |
|
||||
} |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
|
|
1437
src/boost/container/detail/tree.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,75 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
// (C) Copyright John Maddock 2000.
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
// The alignment and Type traits implementation comes from
|
|
||||
// John Maddock's TypeTraits library.
|
|
||||
//
|
|
||||
// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
|
||||
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/move/detail/type_traits.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
using ::boost::move_detail::enable_if; |
|
||||
using ::boost::move_detail::enable_if_and; |
|
||||
using ::boost::move_detail::is_same; |
|
||||
using ::boost::move_detail::is_different; |
|
||||
using ::boost::move_detail::is_pointer; |
|
||||
using ::boost::move_detail::add_reference; |
|
||||
using ::boost::move_detail::add_const; |
|
||||
using ::boost::move_detail::add_const_reference; |
|
||||
using ::boost::move_detail::remove_const; |
|
||||
using ::boost::move_detail::remove_reference; |
|
||||
using ::boost::move_detail::remove_cvref; |
|
||||
using ::boost::move_detail::make_unsigned; |
|
||||
using ::boost::move_detail::is_floating_point; |
|
||||
using ::boost::move_detail::is_integral; |
|
||||
using ::boost::move_detail::is_enum; |
|
||||
using ::boost::move_detail::is_pod; |
|
||||
using ::boost::move_detail::is_empty; |
|
||||
using ::boost::move_detail::is_trivially_destructible; |
|
||||
using ::boost::move_detail::is_trivially_default_constructible; |
|
||||
using ::boost::move_detail::is_trivially_copy_constructible; |
|
||||
using ::boost::move_detail::is_trivially_move_constructible; |
|
||||
using ::boost::move_detail::is_trivially_copy_assignable; |
|
||||
using ::boost::move_detail::is_trivially_move_assignable; |
|
||||
using ::boost::move_detail::is_nothrow_default_constructible; |
|
||||
using ::boost::move_detail::is_nothrow_copy_constructible; |
|
||||
using ::boost::move_detail::is_nothrow_move_constructible; |
|
||||
using ::boost::move_detail::is_nothrow_copy_assignable; |
|
||||
using ::boost::move_detail::is_nothrow_move_assignable; |
|
||||
using ::boost::move_detail::is_nothrow_swappable; |
|
||||
using ::boost::move_detail::alignment_of; |
|
||||
using ::boost::move_detail::aligned_storage; |
|
||||
using ::boost::move_detail::nat; |
|
||||
using ::boost::move_detail::nat2; |
|
||||
using ::boost::move_detail::nat3; |
|
||||
using ::boost::move_detail::natN; |
|
||||
using ::boost::move_detail::max_align_t; |
|
||||
using ::boost::move_detail::is_convertible; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
|
|
@ -1,32 +0,0 @@ |
|||||
#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2017-2017. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/intrusive/detail/value_functors.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
using ::boost::intrusive::value_less; |
|
||||
using ::boost::intrusive::value_equal; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP
|
|
@ -1,51 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013.
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<class T> |
|
||||
struct value_init |
|
||||
{ |
|
||||
value_init() |
|
||||
: m_t() |
|
||||
{} |
|
||||
|
|
||||
operator T &() { return m_t; } |
|
||||
|
|
||||
T &get() { return m_t; } |
|
||||
|
|
||||
T m_t; |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
|
|
@ -1,163 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
#include <cstddef> //std::size_t
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template<typename... Values> |
|
||||
class tuple; |
|
||||
|
|
||||
template<> class tuple<> |
|
||||
{}; |
|
||||
|
|
||||
template<typename Head, typename... Tail> |
|
||||
class tuple<Head, Tail...> |
|
||||
: private tuple<Tail...> |
|
||||
{ |
|
||||
typedef tuple<Tail...> inherited; |
|
||||
|
|
||||
public: |
|
||||
tuple() |
|
||||
: inherited(), m_head() |
|
||||
{} |
|
||||
|
|
||||
template<class U, class ...Args> |
|
||||
tuple(U &&u, Args && ...args) |
|
||||
: inherited(::boost::forward<Args>(args)...), m_head(::boost::forward<U>(u)) |
|
||||
{} |
|
||||
|
|
||||
// Construct tuple from another tuple.
|
|
||||
template<typename... VValues> |
|
||||
tuple(const tuple<VValues...>& other) |
|
||||
: inherited(other.tail()), m_head(other.head()) |
|
||||
{} |
|
||||
|
|
||||
template<typename... VValues> |
|
||||
tuple& operator=(const tuple<VValues...>& other) |
|
||||
{ |
|
||||
m_head = other.head(); |
|
||||
tail() = other.tail(); |
|
||||
return this; |
|
||||
} |
|
||||
|
|
||||
typename add_reference<Head>::type head() { return m_head; } |
|
||||
typename add_reference<const Head>::type head() const { return m_head; } |
|
||||
|
|
||||
inherited& tail() { return *this; } |
|
||||
const inherited& tail() const { return *this; } |
|
||||
|
|
||||
protected: |
|
||||
Head m_head; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<typename... Values> |
|
||||
tuple<Values&&...> forward_as_tuple_impl(Values&&... values) |
|
||||
{ return tuple<Values&&...>(::boost::forward<Values>(values)...); } |
|
||||
|
|
||||
template<int I, typename Tuple> |
|
||||
struct tuple_element; |
|
||||
|
|
||||
template<int I, typename Head, typename... Tail> |
|
||||
struct tuple_element<I, tuple<Head, Tail...> > |
|
||||
{ |
|
||||
typedef typename tuple_element<I-1, tuple<Tail...> >::type type; |
|
||||
}; |
|
||||
|
|
||||
template<typename Head, typename... Tail> |
|
||||
struct tuple_element<0, tuple<Head, Tail...> > |
|
||||
{ |
|
||||
typedef Head type; |
|
||||
}; |
|
||||
|
|
||||
template<int I, typename Tuple> |
|
||||
class get_impl; |
|
||||
|
|
||||
template<int I, typename Head, typename... Values> |
|
||||
class get_impl<I, tuple<Head, Values...> > |
|
||||
{ |
|
||||
typedef typename tuple_element<I-1, tuple<Values...> >::type Element; |
|
||||
typedef get_impl<I-1, tuple<Values...> > Next; |
|
||||
|
|
||||
public: |
|
||||
typedef typename add_reference<Element>::type type; |
|
||||
typedef typename add_const_reference<Element>::type const_type; |
|
||||
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); } |
|
||||
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); } |
|
||||
}; |
|
||||
|
|
||||
template<typename Head, typename... Values> |
|
||||
class get_impl<0, tuple<Head, Values...> > |
|
||||
{ |
|
||||
public: |
|
||||
typedef typename add_reference<Head>::type type; |
|
||||
typedef typename add_const_reference<Head>::type const_type; |
|
||||
static type get(tuple<Head, Values...>& t) { return t.head(); } |
|
||||
static const_type get(const tuple<Head, Values...>& t){ return t.head(); } |
|
||||
}; |
|
||||
|
|
||||
template<int I, typename... Values> |
|
||||
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t) |
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); } |
|
||||
|
|
||||
template<int I, typename... Values> |
|
||||
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t) |
|
||||
{ return get_impl<I, tuple<Values...> >::get(t); } |
|
||||
|
|
||||
////////////////////////////////////////////////////
|
|
||||
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
|
||||
// be used to "unpack" into comma-separated values
|
|
||||
// in a function call.
|
|
||||
////////////////////////////////////////////////////
|
|
||||
|
|
||||
template<std::size_t...> struct index_tuple{ typedef index_tuple type; }; |
|
||||
|
|
||||
template<class S1, class S2> struct concat_index_tuple; |
|
||||
|
|
||||
template<std::size_t... I1, std::size_t... I2> |
|
||||
struct concat_index_tuple<index_tuple<I1...>, index_tuple<I2...>> |
|
||||
: index_tuple<I1..., (sizeof...(I1)+I2)...>{}; |
|
||||
|
|
||||
template<std::size_t N> struct build_number_seq; |
|
||||
|
|
||||
template<std::size_t N> |
|
||||
struct build_number_seq |
|
||||
: concat_index_tuple<typename build_number_seq<N/2>::type |
|
||||
,typename build_number_seq<N - N/2 >::type |
|
||||
>::type |
|
||||
{}; |
|
||||
|
|
||||
template<> struct build_number_seq<0> : index_tuple<>{}; |
|
||||
template<> struct build_number_seq<1> : index_tuple<0>{}; |
|
||||
|
|
||||
}}} //namespace boost { namespace container { namespace dtl {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
|
@ -1,101 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// This code comes from N1953 document by Howard E. Hinnant
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace container { |
|
||||
namespace dtl { |
|
||||
|
|
||||
template <class T, unsigned V> |
|
||||
struct version_type |
|
||||
: public dtl::integral_constant<unsigned, V> |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
namespace impl{ |
|
||||
|
|
||||
template <class T> |
|
||||
struct extract_version |
|
||||
{ |
|
||||
typedef typename T::version type; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct has_version |
|
||||
{ |
|
||||
private: |
|
||||
struct two {char _[2];}; |
|
||||
template <class U> static two test(...); |
|
||||
template <class U> static char test(const typename U::version*); |
|
||||
public: |
|
||||
static const bool value = sizeof(test<T>(0)) == 1; |
|
||||
void dummy(){} |
|
||||
}; |
|
||||
|
|
||||
template <class T, bool = has_version<T>::value> |
|
||||
struct version |
|
||||
{ |
|
||||
static const unsigned value = 1; |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct version<T, true> |
|
||||
{ |
|
||||
static const unsigned value = extract_version<T>::type::value; |
|
||||
}; |
|
||||
|
|
||||
} //namespace impl
|
|
||||
|
|
||||
template <class T> |
|
||||
struct version |
|
||||
: public dtl::integral_constant<unsigned, impl::version<T>::value> |
|
||||
{}; |
|
||||
|
|
||||
template<class T, unsigned N> |
|
||||
struct is_version |
|
||||
{ |
|
||||
static const bool value = |
|
||||
is_same< typename version<T>::type, integral_constant<unsigned, N> >::value; |
|
||||
}; |
|
||||
|
|
||||
} //namespace dtl {
|
|
||||
|
|
||||
typedef dtl::integral_constant<unsigned, 0> version_0; |
|
||||
typedef dtl::integral_constant<unsigned, 1> version_1; |
|
||||
typedef dtl::integral_constant<unsigned, 2> version_2; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP
|
|
@ -1,190 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
|
||||
#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\
|
|
||||
&& !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL) |
|
||||
#define BOOST_CONTAINER_PERFECT_FORWARDING
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\
|
|
||||
&& (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700) |
|
||||
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC_VERSION)
|
|
||||
# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
|
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
|
||||
# endif
|
|
||||
#elif defined(BOOST_MSVC)
|
|
||||
# if _MSC_FULL_VER < 180020827
|
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
|
||||
# endif
|
|
||||
#elif defined(BOOST_CLANG)
|
|
||||
# if !__has_feature(cxx_delegating_constructors)
|
|
||||
# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS
|
|
||||
# endif
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_MSVC) && (_MSC_VER < 1400)
|
|
||||
#define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
|
|
||||
#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
|
|
||||
#endif
|
|
||||
|
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
|
||||
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
|
|
||||
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE
|
|
||||
|
|
||||
//Macros for memset optimization. In most platforms
|
|
||||
//memsetting pointers and floatings is safe and faster.
|
|
||||
//
|
|
||||
//If your platform does not offer these guarantees
|
|
||||
//define these to value zero.
|
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO
|
|
||||
#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1
|
|
||||
#endif
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL
|
|
||||
#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL
|
|
||||
#endif
|
|
||||
|
|
||||
#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2
|
|
||||
#define BOOST_CONTAINER_I ,
|
|
||||
#define BOOST_CONTAINER_DOCIGN(T) T
|
|
||||
#define BOOST_CONTAINER_DOCONLY(T)
|
|
||||
|
|
||||
/*
|
|
||||
we need to import/export our code only if the user has specifically |
|
||||
asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost |
|
||||
libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK |
|
||||
if they want just this one to be dynamically liked: |
|
||||
*/ |
|
||||
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK)
|
|
||||
|
|
||||
/* export if this is our own source, otherwise import: */ |
|
||||
#ifdef BOOST_CONTAINER_SOURCE
|
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT
|
|
||||
#else
|
|
||||
# define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT
|
|
||||
|
|
||||
#endif /* BOOST_CONTAINER_SOURCE */
|
|
||||
#else
|
|
||||
#define BOOST_CONTAINER_DECL
|
|
||||
#endif /* DYN_LINK */
|
|
||||
|
|
||||
//#define BOOST_CONTAINER_DISABLE_FORCEINLINE
|
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE)
|
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
|
||||
#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE)
|
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
|
||||
#elif defined(BOOST_MSVC) && (_MSC_VER <= 1900 || defined(_DEBUG))
|
|
||||
//"__forceinline" and MSVC seems to have some bugs in old versions and in debug mode
|
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
|
||||
#elif defined(BOOST_GCC) && ((__GNUC__ <= 5) || defined(__MINGW32__))
|
|
||||
//Older GCCs and MinGw have problems with forceinline
|
|
||||
#define BOOST_CONTAINER_FORCEINLINE inline
|
|
||||
#else
|
|
||||
#define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE
|
|
||||
#endif
|
|
||||
|
|
||||
//#define BOOST_CONTAINER_DISABLE_NOINLINE
|
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_DISABLE_NOINLINE)
|
|
||||
#define BOOST_CONTAINER_NOINLINE
|
|
||||
#else
|
|
||||
#define BOOST_CONTAINER_NOINLINE BOOST_NOINLINE
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
#if !defined(__has_feature)
|
|
||||
#define BOOST_CONTAINER_HAS_FEATURE(feature) 0
|
|
||||
#else
|
|
||||
#define BOOST_CONTAINER_HAS_FEATURE(feature) __has_feature(feature)
|
|
||||
#endif
|
|
||||
|
|
||||
//Detect address sanitizer
|
|
||||
#if defined(__SANITIZE_ADDRESS__) || BOOST_CONTAINER_HAS_FEATURE(address_sanitizer)
|
|
||||
#define BOOST_CONTAINER_ASAN
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
#if (BOOST_CXX_VERSION < 201703L) || !defined(__cpp_deduction_guides)
|
|
||||
#define BOOST_CONTAINER_NO_CXX17_CTAD
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_DISABLE_ATTRIBUTE_NODISCARD)
|
|
||||
#define BOOST_CONTAINER_ATTRIBUTE_NODISCARD
|
|
||||
#else
|
|
||||
#if defined(BOOST_GCC) && ((BOOST_GCC < 100000) || (__cplusplus < 201703L))
|
|
||||
//Avoid using it in C++ < 17 and GCC < 10 because it warns in SFINAE contexts
|
|
||||
//(see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89070)
|
|
||||
#define BOOST_CONTAINER_ATTRIBUTE_NODISCARD
|
|
||||
#else
|
|
||||
#define BOOST_CONTAINER_ATTRIBUTE_NODISCARD BOOST_ATTRIBUTE_NODISCARD
|
|
||||
#endif
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
//Configuration options:
|
|
||||
|
|
||||
//Define this to use std exception types instead of boost::container's own exception types
|
|
||||
//#define BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
|
||||
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
template <typename T1> |
|
||||
BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore(T1 const&) |
|
||||
{} |
|
||||
|
|
||||
}} //namespace boost::container {
|
|
||||
|
|
||||
#if !(defined BOOST_NO_EXCEPTIONS)
|
|
||||
# define BOOST_CONTAINER_TRY { try
|
|
||||
# define BOOST_CONTAINER_CATCH(x) catch(x)
|
|
||||
# define BOOST_CONTAINER_RETHROW throw;
|
|
||||
# define BOOST_CONTAINER_CATCH_END }
|
|
||||
#else
|
|
||||
# if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
|
||||
# define BOOST_CONTAINER_TRY { if (true)
|
|
||||
# define BOOST_CONTAINER_CATCH(x) else if (false)
|
|
||||
# else
|
|
||||
// warning C4127: conditional expression is constant
|
|
||||
# define BOOST_CONTAINER_TRY { \
|
|
||||
__pragma(warning(push)) \ |
|
||||
__pragma(warning(disable: 4127)) \ |
|
||||
if (true) \ |
|
||||
__pragma(warning(pop)) |
|
||||
# define BOOST_CONTAINER_CATCH(x) else \
|
|
||||
__pragma(warning(push)) \ |
|
||||
__pragma(warning(disable: 4127)) \ |
|
||||
if (false) \ |
|
||||
__pragma(warning(pop)) |
|
||||
# endif
|
|
||||
# define BOOST_CONTAINER_RETHROW
|
|
||||
# define BOOST_CONTAINER_CATCH_END }
|
|
||||
#endif
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
|
|
3067
src/boost/container/flat_map.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
2315
src/boost/container/map.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,201 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2014-2015. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
|
||||
#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/container/throw_exception.hpp>
|
|
||||
#include <cstddef>
|
|
||||
|
|
||||
//!\file
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
/// @cond
|
|
||||
|
|
||||
template<bool Value> |
|
||||
struct new_allocator_bool |
|
||||
{ static const bool value = Value; }; |
|
||||
|
|
||||
template<class T> |
|
||||
class new_allocator; |
|
||||
|
|
||||
/// @endcond
|
|
||||
|
|
||||
//! Specialization of new_allocator for void types
|
|
||||
template<> |
|
||||
class new_allocator<void> |
|
||||
{ |
|
||||
public: |
|
||||
typedef void value_type; |
|
||||
typedef void * pointer; |
|
||||
typedef const void* const_pointer; |
|
||||
//!A integral constant of type bool with value true
|
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment; |
|
||||
//!A integral constant of type bool with value true
|
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal; |
|
||||
// reference-to-void members are impossible
|
|
||||
|
|
||||
//!Obtains an new_allocator that allocates
|
|
||||
//!objects of type T2
|
|
||||
template<class T2> |
|
||||
struct rebind |
|
||||
{ |
|
||||
typedef new_allocator< T2> other; |
|
||||
}; |
|
||||
|
|
||||
//!Default constructor
|
|
||||
//!Never throws
|
|
||||
new_allocator() BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Constructor from other new_allocator.
|
|
||||
//!Never throws
|
|
||||
new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Copy assignment operator from other new_allocator.
|
|
||||
//!Never throws
|
|
||||
new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//!Constructor from related new_allocator.
|
|
||||
//!Never throws
|
|
||||
template<class T2> |
|
||||
new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Swaps two allocators, does nothing
|
|
||||
//!because this new_allocator is stateless
|
|
||||
friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!An new_allocator always compares to true, as memory allocated with one
|
|
||||
//!instance can be deallocated by another instance
|
|
||||
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return true; } |
|
||||
|
|
||||
//!An new_allocator always compares to false, as memory allocated with one
|
|
||||
//!instance can be deallocated by another instance
|
|
||||
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return false; } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
//! This class is a reduced STL-compatible allocator that allocates memory using operator new
|
|
||||
template<class T> |
|
||||
class new_allocator |
|
||||
{ |
|
||||
public: |
|
||||
typedef T value_type; |
|
||||
typedef T * pointer; |
|
||||
typedef const T * const_pointer; |
|
||||
typedef T & reference; |
|
||||
typedef const T & const_reference; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef std::ptrdiff_t difference_type; |
|
||||
//!A integral constant of type bool with value true
|
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) propagate_on_container_move_assignment; |
|
||||
//!A integral constant of type bool with value true
|
|
||||
typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool<true>) is_always_equal; |
|
||||
|
|
||||
//!Obtains an new_allocator that allocates
|
|
||||
//!objects of type T2
|
|
||||
template<class T2> |
|
||||
struct rebind |
|
||||
{ |
|
||||
typedef new_allocator<T2> other; |
|
||||
}; |
|
||||
|
|
||||
//!Default constructor
|
|
||||
//!Never throws
|
|
||||
new_allocator() BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Constructor from other new_allocator.
|
|
||||
//!Never throws
|
|
||||
new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Copy assignment operator from other new_allocator.
|
|
||||
//!Never throws
|
|
||||
new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//!Constructor from related new_allocator.
|
|
||||
//!Never throws
|
|
||||
template<class T2> |
|
||||
new_allocator(const new_allocator<T2> &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!Allocates memory for an array of count elements.
|
|
||||
//!Throws bad_alloc if there is no enough memory
|
|
||||
pointer allocate(size_type count) |
|
||||
{ |
|
||||
const std::size_t max_count = std::size_t(-1)/(2*sizeof(T)); |
|
||||
if(BOOST_UNLIKELY(count > max_count)) |
|
||||
throw_bad_alloc(); |
|
||||
return static_cast<T*>(::operator new(count*sizeof(T))); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates previously allocated memory.
|
|
||||
//!Never throws
|
|
||||
void deallocate(pointer ptr, size_type n) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ |
|
||||
(void)n; |
|
||||
# if __cpp_sized_deallocation
|
|
||||
::operator delete((void*)ptr, n * sizeof(T)); |
|
||||
#else
|
|
||||
::operator delete((void*)ptr); |
|
||||
# endif
|
|
||||
} |
|
||||
|
|
||||
//!Returns the maximum number of elements that could be allocated.
|
|
||||
//!Never throws
|
|
||||
size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return std::size_t(-1)/(2*sizeof(T)); } |
|
||||
|
|
||||
//!Swaps two allocators, does nothing
|
|
||||
//!because this new_allocator is stateless
|
|
||||
friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{} |
|
||||
|
|
||||
//!An new_allocator always compares to true, as memory allocated with one
|
|
||||
//!instance can be deallocated by another instance
|
|
||||
friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return true; } |
|
||||
|
|
||||
//!An new_allocator always compares to false, as memory allocated with one
|
|
||||
//!instance can be deallocated by another instance
|
|
||||
friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW |
|
||||
{ return false; } |
|
||||
}; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP
|
|
@ -1,445 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2016-2016. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_NODE_HANDLE_HPP
|
|
||||
#define BOOST_CONTAINER_NODE_HANDLE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
#include <boost/move/detail/to_raw_pointer.hpp>
|
|
||||
#include <boost/container/allocator_traits.hpp>
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/move/adl_move_swap.hpp>
|
|
||||
|
|
||||
#include <boost/container/detail/mpl.hpp>
|
|
||||
#include <boost/assert.hpp>
|
|
||||
|
|
||||
|
|
||||
//!\file
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
///@cond
|
|
||||
|
|
||||
template<class Value, class KeyMapped> |
|
||||
struct node_handle_keymapped_traits |
|
||||
{ |
|
||||
typedef typename KeyMapped::key_type key_type; |
|
||||
typedef typename KeyMapped::mapped_type mapped_type; |
|
||||
}; |
|
||||
|
|
||||
template<class Value> |
|
||||
struct node_handle_keymapped_traits<Value, void> |
|
||||
{ |
|
||||
typedef Value key_type; |
|
||||
typedef Value mapped_type; |
|
||||
}; |
|
||||
|
|
||||
class node_handle_friend |
|
||||
{ |
|
||||
public: |
|
||||
|
|
||||
template<class NH> |
|
||||
BOOST_CONTAINER_FORCEINLINE static void destroy_alloc(NH &nh) BOOST_NOEXCEPT |
|
||||
{ nh.destroy_alloc(); } |
|
||||
|
|
||||
template<class NH> |
|
||||
BOOST_CONTAINER_FORCEINLINE static typename NH::node_pointer &get_node_pointer(NH &nh) BOOST_NOEXCEPT |
|
||||
{ return nh.get_node_pointer(); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
///@endcond
|
|
||||
|
|
||||
//! A node_handle is an object that accepts ownership of a single element from an associative container.
|
|
||||
//! It may be used to transfer that ownership to another container with compatible nodes. Containers
|
|
||||
//! with compatible nodes have the same node handle type. Elements may be transferred in either direction
|
|
||||
//! between container types in the same row:.
|
|
||||
//!
|
|
||||
//! Container types with compatible nodes
|
|
||||
//!
|
|
||||
//! map<K, T, C1, A> <-> map<K, T, C2, A>
|
|
||||
//!
|
|
||||
//! map<K, T, C1, A> <-> multimap<K, T, C2, A>
|
|
||||
//!
|
|
||||
//! set<K, C1, A> <-> set<K, C2, A>
|
|
||||
//!
|
|
||||
//! set<K, C1, A> <-> multiset<K, C2, A>
|
|
||||
//!
|
|
||||
//! If a node handle is not empty, then it contains an allocator that is equal to the allocator of the container
|
|
||||
//! when the element was extracted. If a node handle is empty, it contains no allocator.
|
|
||||
template <class NodeAllocator, class KeyMapped = void> |
|
||||
class node_handle |
|
||||
{ |
|
||||
typedef NodeAllocator nallocator_type; |
|
||||
typedef allocator_traits<NodeAllocator> nator_traits; |
|
||||
typedef typename nator_traits::value_type priv_node_t; |
|
||||
typedef typename priv_node_t::value_type priv_value_t; |
|
||||
typedef node_handle_keymapped_traits<priv_value_t, KeyMapped> keymapped_t; |
|
||||
|
|
||||
public: |
|
||||
typedef priv_value_t value_type; |
|
||||
typedef typename keymapped_t::key_type key_type; |
|
||||
typedef typename keymapped_t::mapped_type mapped_type; |
|
||||
typedef typename nator_traits::template portable_rebind_alloc |
|
||||
<value_type>::type allocator_type; |
|
||||
|
|
||||
typedef priv_node_t container_node_type; |
|
||||
friend class node_handle_friend; |
|
||||
|
|
||||
///@cond
|
|
||||
private: |
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(node_handle) |
|
||||
|
|
||||
typedef typename nator_traits::pointer node_pointer; |
|
||||
typedef typename dtl::aligned_storage |
|
||||
< sizeof(nallocator_type) |
|
||||
, dtl::alignment_of<nallocator_type>::value |
|
||||
>::type nalloc_storage_t; |
|
||||
|
|
||||
node_pointer m_ptr; |
|
||||
nalloc_storage_t m_nalloc_storage; |
|
||||
|
|
||||
void move_construct_alloc(nallocator_type &al) |
|
||||
{ ::new((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(::boost::move(al)); } |
|
||||
|
|
||||
void destroy_deallocate_node() |
|
||||
{ |
|
||||
boost::movelib::to_raw_pointer(m_ptr)->destructor(this->node_alloc()); |
|
||||
nator_traits::deallocate(this->node_alloc(), m_ptr, 1u); |
|
||||
} |
|
||||
|
|
||||
template<class OtherNodeHandle> |
|
||||
void move_construct_end(OtherNodeHandle &nh) |
|
||||
{ |
|
||||
if(m_ptr){ |
|
||||
::new ((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(::boost::move(nh.node_alloc())); |
|
||||
node_handle_friend::destroy_alloc(nh); |
|
||||
node_handle_friend::get_node_pointer(nh) = node_pointer(); |
|
||||
} |
|
||||
BOOST_ASSERT(nh.empty()); |
|
||||
} |
|
||||
|
|
||||
void destroy_alloc() BOOST_NOEXCEPT |
|
||||
{ static_cast<nallocator_type*>((void*)m_nalloc_storage.data)->~nallocator_type(); } |
|
||||
|
|
||||
node_pointer &get_node_pointer() BOOST_NOEXCEPT |
|
||||
{ return m_ptr; } |
|
||||
|
|
||||
///@endcond
|
|
||||
|
|
||||
public: |
|
||||
//! <b>Effects</b>: Initializes m_ptr to nullptr.
|
|
||||
//!
|
|
||||
//! <b>Postcondition</b>: this->empty()
|
|
||||
BOOST_CXX14_CONSTEXPR node_handle() BOOST_NOEXCEPT |
|
||||
: m_ptr() |
|
||||
{ } |
|
||||
|
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with p.
|
|
||||
//! If p != nullptr copy constructs internal allocator from al.
|
|
||||
node_handle(node_pointer p, const nallocator_type &al) BOOST_NOEXCEPT |
|
||||
: m_ptr(p) |
|
||||
{ |
|
||||
if(m_ptr){ |
|
||||
::new ((void*)m_nalloc_storage.data, boost_container_new_t()) nallocator_type(al); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with a related nh's internal pointer
|
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
|
||||
//!
|
|
||||
//! <b>Postcondition</b>: nh.empty()
|
|
||||
//!
|
|
||||
//! <b>Note</b>: Two node_handle's are related if only one of KeyMapped template parameter
|
|
||||
//! of a node handle is void.
|
|
||||
template<class KeyMapped2> |
|
||||
node_handle( BOOST_RV_REF_BEG node_handle<NodeAllocator, KeyMapped2> BOOST_RV_REF_END nh |
|
||||
, typename dtl::enable_if_c |
|
||||
< ((unsigned)dtl::is_same<KeyMapped, void>::value + |
|
||||
(unsigned)dtl::is_same<KeyMapped2, void>::value) == 1u |
|
||||
>::type* = 0) BOOST_NOEXCEPT |
|
||||
: m_ptr(nh.get()) |
|
||||
{ this->move_construct_end(nh); } |
|
||||
|
|
||||
//! <b>Effects</b>: Constructs a node_handle object initializing internal pointer with nh's internal pointer
|
|
||||
//! and assigns nullptr to the later. If nh's internal pointer was not nullptr, move constructs internal
|
|
||||
//! allocator with nh's internal allocator and destroy nh's internal allocator.
|
|
||||
//!
|
|
||||
//! <b>Postcondition</b>: nh.empty()
|
|
||||
node_handle (BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT |
|
||||
: m_ptr(nh.m_ptr) |
|
||||
{ this->move_construct_end(nh); } |
|
||||
|
|
||||
//! <b>Effects</b>: If !this->empty(), destroys the value_type subobject in the container_node_type object
|
|
||||
//! pointed to by c by calling allocator_traits<impl_defined>::destroy, then deallocates m_ptr by calling
|
|
||||
//! nator_traits::rebind_traits<container_node_type>::deallocate.
|
|
||||
~node_handle() BOOST_NOEXCEPT |
|
||||
{ |
|
||||
if(!this->empty()){ |
|
||||
this->destroy_deallocate_node(); |
|
||||
this->destroy_alloc(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: Either this->empty(), or nator_traits::propagate_on_container_move_assignment is true, or
|
|
||||
//! node_alloc() == nh.node_alloc().
|
|
||||
//!
|
|
||||
//! <b>Effects</b>: If m_ptr != nullptr, destroys the value_type subobject in the container_node_type object
|
|
||||
//! pointed to by m_ptr by calling nator_traits::destroy, then deallocates m_ptr by calling
|
|
||||
//! nator_traits::deallocate. Assigns nh.m_ptr to m_ptr. If this->empty()
|
|
||||
//! or nator_traits::propagate_on_container_move_assignment is true, move assigns nh.node_alloc() to
|
|
||||
//! node_alloc(). Assigns nullptr to nh.m_ptr and assigns nullopt to nh.node_alloc().
|
|
||||
//!
|
|
||||
//! <b>Returns</b>: *this.
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing.
|
|
||||
node_handle & operator=(BOOST_RV_REF(node_handle) nh) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_ASSERT(this->empty() || nator_traits::propagate_on_container_move_assignment::value |
|
||||
|| nator_traits::equal(node_alloc(), nh.node_alloc())); |
|
||||
|
|
||||
bool const was_this_non_null = !this->empty(); |
|
||||
bool const was_nh_non_null = !nh.empty(); |
|
||||
|
|
||||
if(was_nh_non_null){ |
|
||||
if(was_this_non_null){ |
|
||||
this->destroy_deallocate_node(); |
|
||||
if(nator_traits::propagate_on_container_move_assignment::value){ |
|
||||
this->node_alloc() = ::boost::move(nh.node_alloc()); |
|
||||
} |
|
||||
} |
|
||||
else{ |
|
||||
this->move_construct_alloc(nh.node_alloc()); |
|
||||
} |
|
||||
m_ptr = nh.m_ptr; |
|
||||
nh.m_ptr = node_pointer(); |
|
||||
nh.destroy_alloc(); |
|
||||
} |
|
||||
else if(was_this_non_null){ |
|
||||
this->destroy_deallocate_node(); |
|
||||
this->destroy_alloc(); |
|
||||
m_ptr = node_pointer(); |
|
||||
} |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: empty() == false.
|
|
||||
//!
|
|
||||
//! <b>Returns</b>: A reference to the value_type subobject in the container_node_type object pointed to by m_ptr
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing.
|
|
||||
value_type& value() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((dtl::is_same<KeyMapped, void>::value)); |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return m_ptr->get_data(); |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: empty() == false.
|
|
||||
//!
|
|
||||
//! <b>Returns</b>: A non-const reference to the key_type member of the value_type subobject in the
|
|
||||
//! container_node_type object pointed to by m_ptr.
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing.
|
|
||||
//!
|
|
||||
//! <b>Requires</b>: Modifying the key through the returned reference is permitted.
|
|
||||
key_type& key() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((!dtl::is_same<KeyMapped, void>::value)); |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return const_cast<key_type &>(KeyMapped().key_of_value(m_ptr->get_data())); |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: empty() == false.
|
|
||||
//!
|
|
||||
//! <b>Returns</b>: A reference to the mapped_type member of the value_type subobject
|
|
||||
//! in the container_node_type object pointed to by m_ptr
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing.
|
|
||||
mapped_type& mapped() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_STATIC_ASSERT((!dtl::is_same<KeyMapped, void>::value)); |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return KeyMapped().mapped_of_value(m_ptr->get_data()); |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: empty() == false.
|
|
||||
//!
|
|
||||
//! <b>Returns</b>: A copy of the internally hold allocator.
|
|
||||
//!
|
|
||||
//! <b>Throws</b>: Nothing.
|
|
||||
allocator_type get_allocator() const |
|
||||
{ |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return this->node_alloc(); |
|
||||
} |
|
||||
|
|
||||
//! <b>Returns</b>: m_ptr != nullptr.
|
|
||||
//!
|
|
||||
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
|
|
||||
BOOST_CONTAINER_FORCEINLINE explicit operator bool |
|
||||
#else
|
|
||||
private: struct bool_conversion {int for_bool; int for_arg(); }; typedef int bool_conversion::* explicit_bool_arg; |
|
||||
public: BOOST_CONTAINER_FORCEINLINE operator explicit_bool_arg |
|
||||
#endif
|
|
||||
()const BOOST_NOEXCEPT |
|
||||
{ return m_ptr ? &bool_conversion::for_bool : explicit_bool_arg(0); } |
|
||||
|
|
||||
//! <b>Returns</b>: m_ptr == nullptr.
|
|
||||
//!
|
|
||||
bool empty() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
return !this->m_ptr; |
|
||||
} |
|
||||
|
|
||||
//! <b>Requires</b>: this->empty(), or nh.empty(), or nator_traits::propagate_on_container_swap is true, or
|
|
||||
//! node_alloc() == nh.node_alloc().
|
|
||||
//!
|
|
||||
//! <b>Effects</b>: Calls swap(m_ptr, nh.m_ptr). If this->empty(), or nh.empty(), or nator_traits::propagate_on_-
|
|
||||
//! container_swap is true calls swap(node_alloc(), nh.node_alloc()).
|
|
||||
void swap(node_handle &nh) |
|
||||
BOOST_NOEXCEPT_IF(nator_traits::propagate_on_container_swap::value || nator_traits::is_always_equal::value) |
|
||||
{ |
|
||||
BOOST_ASSERT(this->empty() || nh.empty() || nator_traits::propagate_on_container_swap::value |
|
||||
|| nator_traits::equal(node_alloc(), nh.node_alloc())); |
|
||||
|
|
||||
bool const was_this_non_null = !this->empty(); |
|
||||
bool const was_nh_non_null = !nh.empty(); |
|
||||
|
|
||||
if(was_nh_non_null){ |
|
||||
if(was_this_non_null){ |
|
||||
if(nator_traits::propagate_on_container_swap::value){ |
|
||||
::boost::adl_move_swap(this->node_alloc(), nh.node_alloc()); |
|
||||
} |
|
||||
} |
|
||||
else{ |
|
||||
this->move_construct_alloc(nh.node_alloc()); |
|
||||
nh.destroy_alloc(); |
|
||||
} |
|
||||
} |
|
||||
else if(was_this_non_null){ |
|
||||
nh.move_construct_alloc(this->node_alloc()); |
|
||||
this->destroy_alloc(); |
|
||||
} |
|
||||
::boost::adl_move_swap(m_ptr, nh.m_ptr); |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: If this->empty() returns nullptr, otherwise returns m_ptr
|
|
||||
//! resets m_ptr to nullptr and destroys the internal allocator.
|
|
||||
//!
|
|
||||
//! <b>Postcondition</b>: this->empty()
|
|
||||
//!
|
|
||||
//! <b>Note</b>: Non-standard extensions
|
|
||||
node_pointer release() BOOST_NOEXCEPT |
|
||||
{ |
|
||||
node_pointer p(m_ptr); |
|
||||
m_ptr = node_pointer(); |
|
||||
if(p) |
|
||||
this->destroy_alloc(); |
|
||||
return p; |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: Returns m_ptr.
|
|
||||
//!
|
|
||||
//! <b>Note</b>: Non-standard extensions
|
|
||||
node_pointer get() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
return m_ptr; |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: Returns a reference to the internal node allocator.
|
|
||||
//!
|
|
||||
//! <b>Note</b>: Non-standard extensions
|
|
||||
nallocator_type &node_alloc() BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return *static_cast<nallocator_type*>((void*)m_nalloc_storage.data); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
//! <b>Effects</b>: Returns a reference to the internal node allocator.
|
|
||||
//!
|
|
||||
//! <b>Note</b>: Non-standard extensions
|
|
||||
const nallocator_type &node_alloc() const BOOST_NOEXCEPT |
|
||||
{ |
|
||||
BOOST_ASSERT(!empty()); |
|
||||
return *static_cast<const nallocator_type*>((const void*)m_nalloc_storage.data); |
|
||||
} |
|
||||
|
|
||||
//! <b>Effects</b>: x.swap(y).
|
|
||||
//!
|
|
||||
friend void swap(node_handle & x, node_handle & y) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT(x.swap(y))) |
|
||||
{ x.swap(y); } |
|
||||
}; |
|
||||
|
|
||||
//! A class template used to describe the results of inserting a
|
|
||||
//! Container::node_type in a Container with unique keys.
|
|
||||
//! Includes at least the following non-static public data members:
|
|
||||
//!
|
|
||||
//! <ul><li>bool inserted</li>;
|
|
||||
//! <li>Iterator position</li>;
|
|
||||
//! <li>NodeType node</li></ul>
|
|
||||
//!
|
|
||||
//! This type is MoveConstructible, MoveAssignable, DefaultConstructible,
|
|
||||
//! Destructible, and lvalues of that type are swappable
|
|
||||
template<class Iterator, class NodeType> |
|
||||
struct insert_return_type_base |
|
||||
{ |
|
||||
private: |
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(insert_return_type_base) |
|
||||
|
|
||||
public: |
|
||||
insert_return_type_base() |
|
||||
: inserted(false), position(), node() |
|
||||
{} |
|
||||
|
|
||||
insert_return_type_base(BOOST_RV_REF(insert_return_type_base) other) |
|
||||
: inserted(other.inserted), position(other.position), node(boost::move(other.node)) |
|
||||
{} |
|
||||
|
|
||||
template<class RelatedIt, class RelatedNode> |
|
||||
insert_return_type_base(bool insert, RelatedIt it, BOOST_RV_REF(RelatedNode) n) |
|
||||
: inserted(insert), position(it), node(boost::move(n)) |
|
||||
{} |
|
||||
|
|
||||
insert_return_type_base & operator=(BOOST_RV_REF(insert_return_type_base) other) |
|
||||
{ |
|
||||
inserted = other.inserted; |
|
||||
position = other.position; |
|
||||
node = boost::move(other.node); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
bool inserted; |
|
||||
Iterator position; |
|
||||
NodeType node; |
|
||||
}; |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_CONTAINER_NODE_HANDLE_HPP
|
|
@ -1,671 +0,0 @@ |
|||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
|
||||
#define BOOST_CONTAINER_OPTIONS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/container_fwd.hpp>
|
|
||||
#include <boost/intrusive/pack_options.hpp>
|
|
||||
#include <boost/static_assert.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
//! Enumeration used to configure ordered associative containers
|
|
||||
//! with a concrete tree implementation.
|
|
||||
enum tree_type_enum |
|
||||
{ |
|
||||
red_black_tree, |
|
||||
avl_tree, |
|
||||
scapegoat_tree, |
|
||||
splay_tree |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<tree_type_enum TreeType, bool OptimizeSize> |
|
||||
struct tree_opt |
|
||||
{ |
|
||||
static const boost::container::tree_type_enum tree_type = TreeType; |
|
||||
static const bool optimize_size = OptimizeSize; |
|
||||
}; |
|
||||
|
|
||||
typedef tree_opt<red_black_tree, true> tree_assoc_defaults; |
|
||||
|
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//!This option setter specifies the underlying tree type
|
|
||||
//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type) |
|
||||
|
|
||||
//!This option setter specifies if node size is optimized
|
|
||||
//!storing rebalancing data masked into pointers for ordered associative containers
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) |
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::set, \c boost::container::multiset
|
|
||||
//! \c boost::container::map and \c boost::container::multimap.
|
|
||||
//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct tree_assoc_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< tree_assoc_defaults, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef tree_opt<packed_options::tree_type, packed_options::optimize_size> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by tree-based associative containers
|
|
||||
template<class ...Options> |
|
||||
using tree_assoc_options_t = typename boost::container::tree_assoc_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR ASSOCIATIVE HASH-BASED CONTAINERS
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<bool StoreHash, bool CacheBegin, bool LinearBuckets, bool FastmodBuckets> |
|
||||
struct hash_opt |
|
||||
{ |
|
||||
static const bool store_hash = StoreHash; |
|
||||
static const bool cache_begin = CacheBegin; |
|
||||
static const bool linear_buckets = LinearBuckets; |
|
||||
static const bool fastmod_buckets = FastmodBuckets; |
|
||||
}; |
|
||||
|
|
||||
typedef hash_opt<false, false, false, false> hash_assoc_defaults; |
|
||||
|
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//!This option setter specifies if nodes also store the hash value
|
|
||||
//!so that search and rehashing for hash-expensive types is improved.
|
|
||||
//!This option might degrade performance for easy to hash types (like integers)
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) |
|
||||
|
|
||||
//!This option setter specifies if the container will cache the first
|
|
||||
//!non-empty bucket so that begin() is O(1) instead of searching for the
|
|
||||
//!first non-empty bucket (which can be O(bucket_size()))
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin) |
|
||||
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(linear_buckets, bool, Enabled, linear_buckets) |
|
||||
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(fastmod_buckets, bool, Enabled, fastmod_buckets) |
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::hash_set, \c boost::container::hash_multiset
|
|
||||
//! \c boost::container::hash_map and \c boost::container::hash_multimap.
|
|
||||
//! Supported options are: \c boost::container::store_hash
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct hash_assoc_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< hash_assoc_defaults, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef hash_opt<packed_options::store_hash |
|
||||
,packed_options::cache_begin |
|
||||
,packed_options::linear_buckets |
|
||||
,packed_options::fastmod_buckets |
|
||||
> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by hash-based associative containers
|
|
||||
template<class ...Options> |
|
||||
using hash_assoc_options_t = typename boost::container::hash_assoc_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR VECTOR-BASED CONTAINERS
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<class T, class Default> |
|
||||
struct default_if_void |
|
||||
{ |
|
||||
typedef T type; |
|
||||
}; |
|
||||
|
|
||||
template<class Default> |
|
||||
struct default_if_void<void, Default> |
|
||||
{ |
|
||||
typedef Default type; |
|
||||
}; |
|
||||
|
|
||||
template<std::size_t N, std::size_t DefaultN> |
|
||||
struct default_if_zero |
|
||||
{ |
|
||||
static const std::size_t value = N; |
|
||||
}; |
|
||||
|
|
||||
template<std::size_t DefaultN> |
|
||||
struct default_if_zero<0u, DefaultN> |
|
||||
{ |
|
||||
static const std::size_t value = DefaultN; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<class AllocTraits, class StoredSizeType> |
|
||||
struct get_stored_size_type_with_alloctraits |
|
||||
{ |
|
||||
typedef StoredSizeType type; |
|
||||
}; |
|
||||
|
|
||||
template<class AllocTraits> |
|
||||
struct get_stored_size_type_with_alloctraits<AllocTraits, void> |
|
||||
{ |
|
||||
typedef typename AllocTraits::size_type type; |
|
||||
}; |
|
||||
|
|
||||
template<class GrowthType, class StoredSizeType> |
|
||||
struct vector_opt |
|
||||
{ |
|
||||
typedef GrowthType growth_factor_type; |
|
||||
typedef StoredSizeType stored_size_type; |
|
||||
|
|
||||
template<class AllocTraits> |
|
||||
struct get_stored_size_type |
|
||||
: get_stored_size_type_with_alloctraits<AllocTraits, StoredSizeType> |
|
||||
{}; |
|
||||
}; |
|
||||
|
|
||||
class default_next_capacity; |
|
||||
|
|
||||
typedef vector_opt<void, void> vector_null_opt; |
|
||||
|
|
||||
#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//!This growth factor argument specifies that the container should increase its
|
|
||||
//!capacity a 50% when existing capacity is exhausted.
|
|
||||
struct growth_factor_50{}; |
|
||||
|
|
||||
//!This growth factor argument specifies that the container should increase its
|
|
||||
//!capacity a 60% when existing capacity is exhausted.
|
|
||||
struct growth_factor_60{}; |
|
||||
|
|
||||
//!This growth factor argument specifies that the container should increase its
|
|
||||
//!capacity a 100% (doubling its capacity) when existing capacity is exhausted.
|
|
||||
struct growth_factor_100{}; |
|
||||
|
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//!This option setter specifies the growth factor strategy of the underlying vector.
|
|
||||
//!
|
|
||||
//!\tparam GrowthFactor A function object that has the following signature:<br/><br/>
|
|
||||
//!`template<class SizeType>`<br/>
|
|
||||
//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.<br/><br/>
|
|
||||
//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity
|
|
||||
//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other
|
|
||||
//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap`
|
|
||||
//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound,
|
|
||||
//! but the implementation should handle wraparound produced by the growth factor.
|
|
||||
//!
|
|
||||
//!Predefined growth factors that can be passed as arguments to this option are:
|
|
||||
//!\c boost::container::growth_factor_50
|
|
||||
//!\c boost::container::growth_factor_60
|
|
||||
//!\c boost::container::growth_factor_100
|
|
||||
//!
|
|
||||
//!If this option is not specified, a default will be used by the container.
|
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type) |
|
||||
|
|
||||
//!This option specifies the unsigned integer type that a user wants the container
|
|
||||
//!to use to hold size-related information inside a container (e.g. current size, current capacity).
|
|
||||
//!
|
|
||||
//!\tparam StoredSizeType An unsigned integer type. It shall be smaller than than the size
|
|
||||
//! of the size_type deduced from `allocator_traits<A>::size_type` or the same type.
|
|
||||
//!
|
|
||||
//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit
|
|
||||
//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some
|
|
||||
//!memory can be saved for empty vectors. This could potentially performance benefits due to better
|
|
||||
//!cache usage.
|
|
||||
//!
|
|
||||
//!Note that alignment requirements can disallow theoretical space savings. Example:
|
|
||||
//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine
|
|
||||
//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes)
|
|
||||
//!will not save space when comparing two 16-bit size types because usually
|
|
||||
//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit
|
|
||||
//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type.
|
|
||||
//!Measure the size of the resulting container and do not assume a smaller \c stored_size
|
|
||||
//!will always lead to a smaller sizeof(container).
|
|
||||
//!
|
|
||||
//!If a user tries to insert more elements than representable by \c stored_size, vector
|
|
||||
//!will throw a length_error.
|
|
||||
//!
|
|
||||
//!If this option is not specified, `allocator_traits<A>::size_type` (usually std::size_t) will
|
|
||||
//!be used to store size-related information inside the container.
|
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type) |
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::vector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct vector_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< vector_null_opt, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef vector_opt< typename packed_options::growth_factor_type |
|
||||
, typename packed_options::stored_size_type> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::vector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
|
|
||||
template<class ...Options> |
|
||||
using vector_options_t = typename boost::container::vector_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR SMALL-VECTOR CONTAINER
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
//! This option specifies the desired alignment for the value_type stored
|
|
||||
//! in the container.
|
|
||||
//! A value zero represents the natural alignment.
|
|
||||
//!
|
|
||||
//!\tparam Alignment An unsigned integer value. Must be power of two.
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment) |
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<class GrowthType, std::size_t InplaceAlignment> |
|
||||
struct small_vector_opt |
|
||||
{ |
|
||||
typedef GrowthType growth_factor_type; |
|
||||
static const std::size_t inplace_alignment = InplaceAlignment; |
|
||||
}; |
|
||||
|
|
||||
typedef small_vector_opt<void, 0u> small_vector_null_opt; |
|
||||
|
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::small_vector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::inplace_alignment
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct small_vector_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< small_vector_null_opt, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef small_vector_opt< typename packed_options::growth_factor_type |
|
||||
, packed_options::inplace_alignment> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::small_vector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
|
|
||||
template<class ...Options> |
|
||||
using small_vector_options_t = typename boost::container::small_vector_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR STATIC-VECTOR CONTAINER
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
//!This option specifies if the container will throw if in
|
|
||||
//!the static capacity is not sufficient to hold the required
|
|
||||
//!values. If false is specified, insufficient capacity will
|
|
||||
//!lead to BOOST_ASSERT, and if this assertion returns, to undefined behaviour,
|
|
||||
//!which potentially can lead to better static_vector performance.
|
|
||||
//!The default value is true.
|
|
||||
//!
|
|
||||
//!\tparam ThrowOnExhaustion A boolean value. True if throw is required.
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_on_overflow) |
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<bool ThrowOnOverflow, std::size_t InplaceAlignment> |
|
||||
struct static_vector_opt |
|
||||
{ |
|
||||
static const bool throw_on_overflow = ThrowOnOverflow; |
|
||||
static const std::size_t inplace_alignment = InplaceAlignment; |
|
||||
}; |
|
||||
|
|
||||
typedef static_vector_opt<true, 0u> static_vector_null_opt; |
|
||||
|
|
||||
#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::static_vector.
|
|
||||
//! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::inplace_alignment
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct static_vector_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< static_vector_null_opt, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef static_vector_opt< packed_options::throw_on_overflow |
|
||||
, packed_options::inplace_alignment> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::static_vector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
|
|
||||
template<class ...Options> |
|
||||
using static_vector_options_t = typename boost::container::static_vector_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR DEVECTOR CONTAINER
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
//!Thse options specify the relocation strategy of devector.
|
|
||||
//!
|
|
||||
//!Predefined relocation limits that can be passed as arguments to this option are:
|
|
||||
//!\c boost::container::relocate_on_66
|
|
||||
//!\c boost::container::relocate_on_75
|
|
||||
//!\c boost::container::relocate_on_80
|
|
||||
//!\c boost::container::relocate_on_85
|
|
||||
//!\c boost::container::relocate_on_90
|
|
||||
//!
|
|
||||
//!If this option is not specified, a default will be used by the container.
|
|
||||
//!
|
|
||||
//!Note: Repeated insertions at only one end (only back insertions or only front insertions) usually will
|
|
||||
//!lead to a single relocation when `relocate_on_66` is used and two relocations when `relocate_on_90`
|
|
||||
//!is used.
|
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(relocate_on, std::size_t, Fraction, free_fraction) |
|
||||
|
|
||||
struct relocate_on_66 : public relocate_on<3U>{}; |
|
||||
|
|
||||
struct relocate_on_75 : public relocate_on<4U> {}; |
|
||||
|
|
||||
struct relocate_on_80 : public relocate_on<5U> {}; |
|
||||
|
|
||||
struct relocate_on_85 : public relocate_on<7U> {}; |
|
||||
|
|
||||
struct relocate_on_90 : public relocate_on<10U> {}; |
|
||||
|
|
||||
template<class GrowthType, class StoredSizeType, std::size_t FreeFraction> |
|
||||
struct devector_opt |
|
||||
: vector_opt<GrowthType, StoredSizeType> |
|
||||
{ |
|
||||
static const std::size_t free_fraction = FreeFraction; |
|
||||
}; |
|
||||
|
|
||||
typedef devector_opt<void, void, 0u> devector_null_opt; |
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
//!This relocation condition option specifies that the container will never relocate
|
|
||||
//!elements when there is no space at the side the insertion should
|
|
||||
//!take place
|
|
||||
struct relocate_never; |
|
||||
|
|
||||
//!This relocation condition option specifies that the container will relocate
|
|
||||
//!all elements when there is no space at the side the insertion should
|
|
||||
//!take place and memory usage is below 66% (2/3)
|
|
||||
struct relocate_on_66; |
|
||||
|
|
||||
//!This relocation condition option specifies that the container will relocate
|
|
||||
//!all elements when there is no space at the side the insertion should
|
|
||||
//!take place and memory usage is below 75% (3/4)
|
|
||||
struct relocate_on_75; |
|
||||
|
|
||||
//!This relocation condition option specifies that the container will relocate
|
|
||||
//!all elements when there is no space at the side the insertion should
|
|
||||
//!take place and memory usage is below 80% (4/5)
|
|
||||
struct relocate_on_80; |
|
||||
|
|
||||
//!This relocation condition option specifies that the container will relocate
|
|
||||
//!all elements when there is no space at the side the insertion should
|
|
||||
//!take place and memory usage is below 85% (6/7)
|
|
||||
struct relocate_on_85; |
|
||||
|
|
||||
//!This relocation condition option specifies that the container will relocate
|
|
||||
//!all elements when there is no space at the side the insertion should
|
|
||||
//!take place and memory usage is below 90% (9/10)
|
|
||||
struct relocate_on_90; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::devector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor, \c boost::container::stored_size
|
|
||||
//! and \c boost::container::relocate_on
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct devector_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< devector_null_opt, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef devector_opt< typename packed_options::growth_factor_type |
|
||||
, typename packed_options::stored_size_type |
|
||||
, packed_options::free_fraction |
|
||||
> implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::devector.
|
|
||||
//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size
|
|
||||
template<class ...Options> |
|
||||
using devector_options_t = typename boost::container::devector_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
//
|
|
||||
// OPTIONS FOR DEQUE-BASED CONTAINERS
|
|
||||
//
|
|
||||
//
|
|
||||
////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<std::size_t BlockBytes, std::size_t BlockSize> |
|
||||
struct deque_opt |
|
||||
{ |
|
||||
static const std::size_t block_bytes = BlockBytes; |
|
||||
static const std::size_t block_size = BlockSize; |
|
||||
BOOST_STATIC_ASSERT_MSG(!(block_bytes && block_size), "block_bytes and block_size can't be specified at the same time"); |
|
||||
}; |
|
||||
|
|
||||
typedef deque_opt<0u, 0u> deque_null_opt; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
//! Helper metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::deque.
|
|
||||
//! Supported options are: \c boost::container::block_bytes
|
|
||||
#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
template<class ...Options> |
|
||||
#else
|
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void> |
|
||||
#endif
|
|
||||
struct deque_options |
|
||||
{ |
|
||||
/// @cond
|
|
||||
typedef typename ::boost::intrusive::pack_options |
|
||||
< deque_null_opt, |
|
||||
#if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES)
|
|
||||
O1, O2, O3, O4 |
|
||||
#else
|
|
||||
Options... |
|
||||
#endif
|
|
||||
>::type packed_options; |
|
||||
typedef deque_opt< packed_options::block_bytes, packed_options::block_size > implementation_defined; |
|
||||
/// @endcond
|
|
||||
typedef implementation_defined type; |
|
||||
}; |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
|
||||
|
|
||||
//! Helper alias metafunction to combine options into a single type to be used
|
|
||||
//! by \c boost::container::deque.
|
|
||||
//! Supported options are: \c boost::container::block_bytes
|
|
||||
template<class ...Options> |
|
||||
using deque_options_t = typename boost::container::deque_options<Options...>::type; |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
//!This option specifies the maximum size of a block in bytes: this delimites the number of contiguous elements
|
|
||||
//!that will be allocated by deque as min(1u, BlockBytes/sizeof(value_type))
|
|
||||
//!A value zero represents the default value.
|
|
||||
//!
|
|
||||
//!\tparam BlockBytes An unsigned integer value.
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(block_bytes, std::size_t, BlockBytes, block_bytes) |
|
||||
|
|
||||
//!This option specifies the size of a block, delimites the number of contiguous elements
|
|
||||
//!that will be allocated by deque as BlockSize.
|
|
||||
//!A value zero represents the default value.
|
|
||||
//!
|
|
||||
//!\tparam BlockBytes An unsigned integer value.
|
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(block_size, std::size_t, BlockSize, block_size) |
|
||||
|
|
||||
} //namespace container {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP
|
|
3625
src/boost/container/string.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,295 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2012-2013. 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 http://www.boost.org/libs/container for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
|
|
||||
#define BOOST_CONTAINER_THROW_EXCEPTION_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/container/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/workaround.hpp>
|
|
||||
|
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
|
||||
#include <exception> //for std exception base
|
|
||||
|
|
||||
# if defined(BOOST_CONTAINER_USE_STD_EXCEPTIONS)
|
|
||||
#include <stdexcept> //for std::out_of_range, std::length_error, std::logic_error, std::runtime_error
|
|
||||
#include <string> //for implicit std::string conversion
|
|
||||
#include <new> //for std::bad_alloc
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
typedef std::bad_alloc bad_alloc_t; |
|
||||
typedef std::out_of_range out_of_range_t; |
|
||||
typedef std::length_error length_error_t; |
|
||||
typedef std::logic_error logic_error_t; |
|
||||
typedef std::runtime_error runtime_error_t; |
|
||||
|
|
||||
}} //namespace boost::container
|
|
||||
|
|
||||
# else //!BOOST_CONTAINER_USE_STD_EXCEPTIONS
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE exception |
|
||||
: public ::std::exception |
|
||||
{ |
|
||||
typedef ::std::exception std_exception_t; |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
//msg must be a static string (guaranteed by callers)
|
|
||||
explicit exception(const char *msg) |
|
||||
: std_exception_t(), m_msg(msg) |
|
||||
{} |
|
||||
|
|
||||
virtual const char *what() const BOOST_NOEXCEPT_OR_NOTHROW BOOST_OVERRIDE |
|
||||
{ return m_msg ? m_msg : "unknown boost::container exception"; } |
|
||||
|
|
||||
private: |
|
||||
const char *m_msg; |
|
||||
}; |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE bad_alloc |
|
||||
: public exception |
|
||||
{ |
|
||||
public: |
|
||||
bad_alloc() |
|
||||
: exception("boost::container::bad_alloc thrown") |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
typedef bad_alloc bad_alloc_t; |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE out_of_range |
|
||||
: public exception |
|
||||
{ |
|
||||
public: |
|
||||
explicit out_of_range(const char *msg) |
|
||||
: exception(msg) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
typedef out_of_range out_of_range_t; |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE length_error |
|
||||
: public exception |
|
||||
{ |
|
||||
public: |
|
||||
explicit length_error(const char *msg) |
|
||||
: exception(msg) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
typedef length_error length_error_t; |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE logic_error |
|
||||
: public exception |
|
||||
{ |
|
||||
public: |
|
||||
explicit logic_error(const char *msg) |
|
||||
: exception(msg) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
typedef logic_error logic_error_t; |
|
||||
|
|
||||
class BOOST_SYMBOL_VISIBLE runtime_error |
|
||||
: public exception |
|
||||
{ |
|
||||
public: |
|
||||
explicit runtime_error(const char *msg) |
|
||||
: exception(msg) |
|
||||
{} |
|
||||
}; |
|
||||
|
|
||||
typedef runtime_error runtime_error_t; |
|
||||
|
|
||||
} // namespace boost {
|
|
||||
} // namespace container {
|
|
||||
|
|
||||
# endif
|
|
||||
#else
|
|
||||
#include <boost/assert.hpp>
|
|
||||
#include <cstdlib> //for std::abort
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace container { |
|
||||
|
|
||||
#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS)
|
|
||||
//The user must provide definitions for the following functions
|
|
||||
|
|
||||
BOOST_NORETURN void throw_bad_alloc(); |
|
||||
|
|
||||
BOOST_NORETURN void throw_out_of_range(const char* str); |
|
||||
|
|
||||
BOOST_NORETURN void throw_length_error(const char* str); |
|
||||
|
|
||||
BOOST_NORETURN void throw_logic_error(const char* str); |
|
||||
|
|
||||
BOOST_NORETURN void throw_runtime_error(const char* str); |
|
||||
|
|
||||
#elif defined(BOOST_NO_EXCEPTIONS)
|
|
||||
|
|
||||
BOOST_NORETURN inline void throw_bad_alloc() |
|
||||
{ |
|
||||
BOOST_ASSERT(!"boost::container bad_alloc thrown"); |
|
||||
std::abort(); |
|
||||
} |
|
||||
|
|
||||
BOOST_NORETURN inline void throw_out_of_range(const char* str) |
|
||||
{ |
|
||||
boost::container::ignore(str); |
|
||||
BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str); |
|
||||
std::abort(); |
|
||||
} |
|
||||
|
|
||||
BOOST_NORETURN inline void throw_length_error(const char* str) |
|
||||
{ |
|
||||
boost::container::ignore(str); |
|
||||
BOOST_ASSERT_MSG(!"boost::container length_error thrown", str); |
|
||||
std::abort(); |
|
||||
} |
|
||||
|
|
||||
BOOST_NORETURN inline void throw_logic_error(const char* str) |
|
||||
{ |
|
||||
boost::container::ignore(str); |
|
||||
BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str); |
|
||||
std::abort(); |
|
||||
} |
|
||||
|
|
||||
BOOST_NORETURN inline void throw_runtime_error(const char* str) |
|
||||
{ |
|
||||
boost::container::ignore(str); |
|
||||
BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str); |
|
||||
std::abort(); |
|
||||
} |
|
||||
|
|
||||
#else //defined(BOOST_NO_EXCEPTIONS)
|
|
||||
|
|
||||
//! Exception callback called by Boost.Container when fails to allocate the requested storage space.
|
|
||||
//! <ul>
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
|
|
||||
//! <code>boost::container::bad_alloc(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
|
|
||||
//! <code>std::bad_alloc(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
|
||||
//! is NOT defined <code>BOOST_ASSERT(!"boost::container bad_alloc thrown")</code> is called
|
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
|
||||
//! </ul>
|
|
||||
BOOST_NORETURN inline void throw_bad_alloc() |
|
||||
{ |
|
||||
throw bad_alloc_t(); |
|
||||
} |
|
||||
|
|
||||
//! Exception callback called by Boost.Container to signal arguments out of range.
|
|
||||
//! <ul>
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
|
|
||||
//! <code>boost::container::out_of_range(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
|
|
||||
//! <code>std::out_of_range(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str)</code> is called
|
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
|
||||
//! </ul>
|
|
||||
BOOST_NORETURN inline void throw_out_of_range(const char* str) |
|
||||
{ |
|
||||
throw out_of_range_t(str); |
|
||||
} |
|
||||
|
|
||||
//! Exception callback called by Boost.Container to signal errors resizing.
|
|
||||
//! <ul>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
|
|
||||
//! <code>boost::container::length_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
|
|
||||
//! <code>std::length_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container length_error thrown", str)</code> is called
|
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
|
||||
//! </ul>
|
|
||||
BOOST_NORETURN inline void throw_length_error(const char* str) |
|
||||
{ |
|
||||
throw length_error_t(str); |
|
||||
} |
|
||||
|
|
||||
//! Exception callback called by Boost.Container to report errors in the internal logical
|
|
||||
//! of the program, such as violation of logical preconditions or class invariants.
|
|
||||
//! <ul>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
|
|
||||
//! <code>boost::container::logic_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
|
|
||||
//! <code>std::logic_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str)</code> is called
|
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
|
||||
//! </ul>
|
|
||||
BOOST_NORETURN inline void throw_logic_error(const char* str) |
|
||||
{ |
|
||||
throw logic_error_t(str); |
|
||||
} |
|
||||
|
|
||||
//! Exception callback called by Boost.Container to report errors that can only be detected during runtime.
|
|
||||
//! <ul>
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is NOT defined
|
|
||||
//! <code>boost::container::runtime_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is NOT defined and BOOST_CONTAINER_USE_STD_EXCEPTIONS is defined
|
|
||||
//! <code>std::runtime_error(str)</code> is thrown.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS
|
|
||||
//! is NOT defined <code>BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str)</code> is called
|
|
||||
//! and <code>std::abort()</code> if the former returns.</li>
|
|
||||
//!
|
|
||||
//! <li>If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined
|
|
||||
//! the user must provide an implementation and the function should not return.</li>
|
|
||||
//! </ul>
|
|
||||
BOOST_NORETURN inline void throw_runtime_error(const char* str) |
|
||||
{ |
|
||||
throw runtime_error_t(str); |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
}} //namespace boost { namespace container {
|
|
||||
|
|
||||
#include <boost/container/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP
|
|
3188
src/boost/container/vector.hpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,17 +0,0 @@ |
|||||
/*
|
|
||||
Copyright 2019 Glen Joseph Fernandes |
|
||||
(glenjofe@gmail.com) |
|
||||
|
|
||||
Distributed under the Boost Software License, Version 1.0. |
|
||||
(http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
*/ |
|
||||
#ifndef BOOST_CORE_USE_DEFAULT_HPP
|
|
||||
#define BOOST_CORE_USE_DEFAULT_HPP
|
|
||||
|
|
||||
namespace boost { |
|
||||
|
|
||||
struct use_default { }; |
|
||||
|
|
||||
} /* boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,193 +0,0 @@ |
|||||
/* Copyright 2003-2013 Joaquin M Lopez Munoz.
|
|
||||
* 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/detail/select_type.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 */ |
|
||||
|
|
||||
template<typename Allocator> |
|
||||
struct rebinder |
|
||||
{ |
|
||||
template<typename Type> |
|
||||
struct result |
|
||||
{ |
|
||||
#ifdef BOOST_NO_CXX11_ALLOCATOR
|
|
||||
typedef typename Allocator::BOOST_NESTED_TEMPLATE |
|
||||
rebind<Type>::other other; |
|
||||
#else
|
|
||||
typedef typename std::allocator_traits<Allocator>::BOOST_NESTED_TEMPLATE |
|
||||
rebind_alloc<Type> 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: |
|
||||
boost::detail::if_true< |
|
||||
is_partial_std_allocator<Allocator>::value |
|
||||
>::template then< |
|
||||
partial_std_allocator_rebind_to<Allocator,Type>, |
|
||||
compliant_allocator_rebind_to<Allocator,Type> |
|
||||
>::type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
/* allocator-independent versions of construct and destroy */ |
|
||||
|
|
||||
template<typename Type> |
|
||||
void construct(void* p,const Type& t) |
|
||||
{ |
|
||||
new (p) Type(t); |
|
||||
} |
|
||||
|
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
|
|
||||
/* MSVC++ issues spurious warnings about unreferencend formal parameters
|
|
||||
* in destroy<Type> when Type is a class with trivial dtor. |
|
||||
*/ |
|
||||
|
|
||||
#pragma warning(push)
|
|
||||
#pragma warning(disable:4100)
|
|
||||
#endif
|
|
||||
|
|
||||
template<typename Type> |
|
||||
void destroy(const Type* p) |
|
||||
{ |
|
||||
|
|
||||
#if BOOST_WORKAROUND(__SUNPRO_CC,BOOST_TESTED_AT(0x590))
|
|
||||
const_cast<Type*>(p)->~Type(); |
|
||||
#else
|
|
||||
p->~Type(); |
|
||||
#endif
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1500))
|
|
||||
#pragma warning(pop)
|
|
||||
#endif
|
|
||||
|
|
||||
} /* namespace boost::detail::allocator */ |
|
||||
|
|
||||
} /* namespace boost::detail */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,195 +0,0 @@ |
|||||
// Copyright David Abrahams 2002.
|
|
||||
// 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)
|
|
||||
#ifndef INDIRECT_TRAITS_DWA2002131_HPP
|
|
||||
# define INDIRECT_TRAITS_DWA2002131_HPP
|
|
||||
# include <boost/type_traits/integral_constant.hpp>
|
|
||||
# include <boost/type_traits/is_function.hpp>
|
|
||||
# include <boost/type_traits/is_reference.hpp>
|
|
||||
# include <boost/type_traits/is_pointer.hpp>
|
|
||||
# include <boost/type_traits/is_class.hpp>
|
|
||||
# include <boost/type_traits/is_const.hpp>
|
|
||||
# include <boost/type_traits/is_volatile.hpp>
|
|
||||
# include <boost/type_traits/is_member_function_pointer.hpp>
|
|
||||
# include <boost/type_traits/is_member_pointer.hpp>
|
|
||||
# include <boost/type_traits/remove_cv.hpp>
|
|
||||
# include <boost/type_traits/remove_reference.hpp>
|
|
||||
# include <boost/type_traits/remove_pointer.hpp>
|
|
||||
|
|
||||
# include <boost/detail/workaround.hpp>
|
|
||||
# include <boost/detail/select_type.hpp>
|
|
||||
|
|
||||
|
|
||||
namespace boost { namespace detail { |
|
||||
|
|
||||
namespace indirect_traits { |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_const : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_const<T const&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
|
|
||||
template<class T> |
|
||||
struct is_reference_to_const<T const volatile&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
# endif
|
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_function : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_function<T&> : is_function<T> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_pointer_to_function : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
// There's no such thing as a pointer-to-cv-function, so we don't need
|
|
||||
// specializations for those
|
|
||||
template <class T> |
|
||||
struct is_pointer_to_function<T*> : is_function<T> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_member_function_pointer_impl : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_member_function_pointer_impl<T&> |
|
||||
: is_member_function_pointer<typename remove_cv<T>::type> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_member_function_pointer |
|
||||
: is_reference_to_member_function_pointer_impl<T> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_function_pointer_aux |
|
||||
: boost::integral_constant<bool, |
|
||||
is_reference<T>::value && |
|
||||
is_pointer_to_function< |
|
||||
typename remove_cv< |
|
||||
typename remove_reference<T>::type |
|
||||
>::type |
|
||||
>::value |
|
||||
> |
|
||||
{ |
|
||||
// There's no such thing as a pointer-to-cv-function, so we don't need specializations for those
|
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_function_pointer |
|
||||
: boost::detail::if_true< |
|
||||
is_reference_to_function<T>::value |
|
||||
>::template then< |
|
||||
boost::false_type |
|
||||
, is_reference_to_function_pointer_aux<T> |
|
||||
>::type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_non_const |
|
||||
: boost::integral_constant<bool, |
|
||||
is_reference<T>::value && |
|
||||
!is_reference_to_const<T>::value |
|
||||
> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_volatile : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_volatile<T volatile&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
|
|
||||
template <class T> |
|
||||
struct is_reference_to_volatile<T const volatile&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
# endif
|
|
||||
|
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_pointer : boost::false_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_pointer<T*&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_pointer<T* const&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_pointer<T* volatile&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_pointer<T* const volatile&> : boost::true_type |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_reference_to_class |
|
||||
: boost::integral_constant<bool, |
|
||||
is_reference<T>::value && |
|
||||
is_class< |
|
||||
typename remove_cv< |
|
||||
typename remove_reference<T>::type |
|
||||
>::type |
|
||||
>::value |
|
||||
> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
template <class T> |
|
||||
struct is_pointer_to_class |
|
||||
: boost::integral_constant<bool, |
|
||||
is_pointer<T>::value && |
|
||||
is_class< |
|
||||
typename remove_cv< |
|
||||
typename remove_pointer<T>::type |
|
||||
>::type |
|
||||
>::value |
|
||||
> |
|
||||
{ |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
} |
|
||||
|
|
||||
using namespace indirect_traits; |
|
||||
|
|
||||
}} // namespace boost::python::detail
|
|
||||
|
|
||||
#endif // INDIRECT_TRAITS_DWA2002131_HPP
|
|
@ -1,273 +0,0 @@ |
|||||
#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED
|
|
||||
#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED
|
|
||||
|
|
||||
//
|
|
||||
// boost/detail/interlocked.hpp
|
|
||||
//
|
|
||||
// Copyright 2005 Peter Dimov
|
|
||||
// Copyright 2018, 2019 Andrey Semashev
|
|
||||
//
|
|
||||
// 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)
|
|
||||
//
|
|
||||
|
|
||||
#include <boost/config.hpp>
|
|
||||
|
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
// BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
// VC9 has intrin.h, but it collides with <utility>
|
|
||||
#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets.
|
|
||||
#elif defined( __MINGW64_VERSION_MAJOR )
|
|
||||
|
|
||||
// MinGW-w64 provides intrin.h for both 32 and 64-bit targets.
|
|
||||
# define BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
#elif defined( __CYGWIN__ )
|
|
||||
|
|
||||
// Cygwin and Cygwin64 provide intrin.h. On Cygwin64 we have to use intrin.h because it's an LP64 target,
|
|
||||
// where long is 64-bit and therefore _Interlocked* functions have different signatures.
|
|
||||
# define BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
// Intel C++ on Windows on VC10+ stdlib
|
|
||||
#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
// clang-cl on Windows on VC10+ stdlib
|
|
||||
#elif defined( __clang__ ) && defined( _MSC_VER ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_HAS_INTRIN_H
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(__LP64__)
|
|
||||
#define BOOST_INTERLOCKED_LONG32 long
|
|
||||
#else
|
|
||||
#define BOOST_INTERLOCKED_LONG32 int
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined( BOOST_USE_WINDOWS_H )
|
|
||||
|
|
||||
# include <windows.h>
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
InterlockedExchangePointer((void**)(dest), (void*)(exchange)) |
|
||||
|
|
||||
#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_INTERLOCKED_HAS_INTRIN_H )
|
|
||||
|
|
||||
#include <intrin.h>
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
_InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
_InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
_InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
_InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
_InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
|
|
||||
// Note: Though MSVC-12 defines _InterlockedCompareExchangePointer and _InterlockedExchangePointer in intrin.h, the latter
|
|
||||
// is actually broken as it conflicts with winnt.h from Windows SDK 8.1.
|
|
||||
# if (defined(_MSC_VER) && _MSC_VER >= 1900) || \
|
|
||||
(defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_ARM64)) |
|
||||
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
_InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
_InterlockedExchangePointer((void**)(dest), (void*)(exchange)) |
|
||||
|
|
||||
# else
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare))) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
((void*)BOOST_INTERLOCKED_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange))) |
|
||||
|
|
||||
# endif
|
|
||||
|
|
||||
#elif defined(_WIN32_WCE)
|
|
||||
|
|
||||
#if _WIN32_WCE >= 0x600
|
|
||||
|
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl _InterlockedIncrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl _InterlockedDecrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl _InterlockedCompareExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl _InterlockedExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl _InterlockedExchangeAdd( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
_InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
_InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
_InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
_InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
_InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
|
|
||||
#else // _WIN32_WCE >= 0x600
|
|
||||
|
|
||||
// under Windows CE we still have old-style Interlocked* functions
|
|
||||
|
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl InterlockedIncrement( BOOST_INTERLOCKED_LONG32 * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl InterlockedDecrement( BOOST_INTERLOCKED_LONG32 * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl InterlockedCompareExchange( BOOST_INTERLOCKED_LONG32 *, BOOST_INTERLOCKED_LONG32, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl InterlockedExchange( BOOST_INTERLOCKED_LONG32 *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 __cdecl InterlockedExchangeAdd( BOOST_INTERLOCKED_LONG32 *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
|
|
||||
#endif // _WIN32_WCE >= 0x600
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare))) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
((void*)BOOST_INTERLOCKED_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange))) |
|
||||
|
|
||||
#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN )
|
|
||||
|
|
||||
# if defined( __CLRCALL_PURE_OR_CDECL )
|
|
||||
# define BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL __CLRCALL_PURE_OR_CDECL
|
|
||||
# else
|
|
||||
# define BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL __cdecl
|
|
||||
# endif
|
|
||||
|
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedIncrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedDecrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_LONG32 BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
|
|
||||
# if defined( BOOST_MSVC ) && BOOST_MSVC >= 1310
|
|
||||
# pragma intrinsic( _InterlockedIncrement )
|
|
||||
# pragma intrinsic( _InterlockedDecrement )
|
|
||||
# pragma intrinsic( _InterlockedCompareExchange )
|
|
||||
# pragma intrinsic( _InterlockedExchange )
|
|
||||
# pragma intrinsic( _InterlockedExchangeAdd )
|
|
||||
# endif
|
|
||||
|
|
||||
# if defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM64)
|
|
||||
|
|
||||
extern "C" void* BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); |
|
||||
extern "C" void* BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL _InterlockedExchangePointer( void* volatile *, void* ); |
|
||||
|
|
||||
# if defined( BOOST_MSVC ) && BOOST_MSVC >= 1310
|
|
||||
# pragma intrinsic( _InterlockedCompareExchangePointer )
|
|
||||
# pragma intrinsic( _InterlockedExchangePointer )
|
|
||||
# endif
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
_InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
_InterlockedExchangePointer((void**)(dest), (void*)(exchange)) |
|
||||
|
|
||||
# else
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare))) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
((void*)BOOST_INTERLOCKED_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange))) |
|
||||
|
|
||||
# endif
|
|
||||
|
|
||||
# undef BOOST_INTERLOCKED_CLRCALL_PURE_OR_CDECL
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
_InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
_InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
_InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
_InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
_InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
|
|
||||
#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
|
|
||||
|
|
||||
#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport)
|
|
||||
|
|
||||
namespace boost |
|
||||
{ |
|
||||
|
|
||||
namespace detail |
|
||||
{ |
|
||||
|
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT BOOST_INTERLOCKED_LONG32 __stdcall InterlockedIncrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT BOOST_INTERLOCKED_LONG32 __stdcall InterlockedDecrement( BOOST_INTERLOCKED_LONG32 volatile * ); |
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT BOOST_INTERLOCKED_LONG32 __stdcall InterlockedCompareExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT BOOST_INTERLOCKED_LONG32 __stdcall InterlockedExchange( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT BOOST_INTERLOCKED_LONG32 __stdcall InterlockedExchangeAdd( BOOST_INTERLOCKED_LONG32 volatile *, BOOST_INTERLOCKED_LONG32 ); |
|
||||
|
|
||||
# if defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM64)
|
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); |
|
||||
extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); |
|
||||
# endif
|
|
||||
|
|
||||
} // namespace detail
|
|
||||
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
# define BOOST_INTERLOCKED_INCREMENT(dest) \
|
|
||||
::boost::detail::InterlockedIncrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_DECREMENT(dest) \
|
|
||||
::boost::detail::InterlockedDecrement((BOOST_INTERLOCKED_LONG32*)(dest)) |
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE(dest, exchange, compare) \
|
|
||||
::boost::detail::InterlockedCompareExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange), (BOOST_INTERLOCKED_LONG32)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE(dest, exchange) \
|
|
||||
::boost::detail::InterlockedExchange((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(exchange)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_ADD(dest, add) \
|
|
||||
::boost::detail::InterlockedExchangeAdd((BOOST_INTERLOCKED_LONG32*)(dest), (BOOST_INTERLOCKED_LONG32)(add)) |
|
||||
|
|
||||
# if defined(_M_IA64) || defined(_M_AMD64) || defined(_M_ARM64)
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
::boost::detail::InterlockedCompareExchangePointer((void**)(dest), (void*)(exchange), (void*)(compare)) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
::boost::detail::InterlockedExchangePointer((void**)(dest), (void*)(exchange)) |
|
||||
# else
|
|
||||
# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest, exchange, compare) \
|
|
||||
((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((BOOST_INTERLOCKED_LONG32 volatile*)(dest),(BOOST_INTERLOCKED_LONG32)(exchange),(BOOST_INTERLOCKED_LONG32)(compare))) |
|
||||
# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest, exchange) \
|
|
||||
((void*)BOOST_INTERLOCKED_EXCHANGE((BOOST_INTERLOCKED_LONG32*)(dest),(BOOST_INTERLOCKED_LONG32)(exchange))) |
|
||||
# endif
|
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
# error "Interlocked intrinsics not available"
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED
|
|
@ -1,36 +0,0 @@ |
|||||
// (C) Copyright David Abrahams 2001.
|
|
||||
// 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 http://www.boost.org for most recent version including documentation.
|
|
||||
|
|
||||
// Revision History
|
|
||||
// 09 Feb 01 Applied John Maddock's Borland patch Moving <true>
|
|
||||
// specialization to unspecialized template (David Abrahams)
|
|
||||
// 06 Feb 01 Created (David Abrahams)
|
|
||||
|
|
||||
#ifndef SELECT_TYPE_DWA20010206_HPP
|
|
||||
# define SELECT_TYPE_DWA20010206_HPP
|
|
||||
|
|
||||
namespace boost { namespace detail { |
|
||||
|
|
||||
// Template class if_true -- select among 2 types based on a bool constant expression
|
|
||||
// Usage:
|
|
||||
// typename if_true<(bool_const_expression)>::template then<true_type, false_type>::type
|
|
||||
|
|
||||
// HP aCC cannot deal with missing names for template value parameters
|
|
||||
template <bool b> struct if_true |
|
||||
{ |
|
||||
template <class T, class F> |
|
||||
struct then { typedef T type; }; |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct if_true<false> |
|
||||
{ |
|
||||
template <class T, class F> |
|
||||
struct then { typedef F type; }; |
|
||||
}; |
|
||||
}} |
|
||||
#endif // SELECT_TYPE_DWA20010206_HPP
|
|
@ -1,116 +0,0 @@ |
|||||
/* Copyright 2006-2015 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP
|
|
||||
#define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/assoc_container_factory_fwd.hpp>
|
|
||||
#include <boost/flyweight/detail/is_placeholder_expr.hpp>
|
|
||||
#include <boost/flyweight/detail/nested_xxx_if_not_ph.hpp>
|
|
||||
#include <boost/flyweight/factory_tag.hpp>
|
|
||||
#include <boost/mpl/apply.hpp>
|
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
|
||||
#include <boost/mpl/if.hpp>
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
#include <utility>
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{namespace flyweights{namespace detail{ |
|
||||
BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(iterator) |
|
||||
BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(value_type) |
|
||||
}}} /* namespace boost::flyweights::detail */ |
|
||||
|
|
||||
/* Factory class using a given associative container.
|
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template<typename Container> |
|
||||
class assoc_container_factory_class:public factory_marker |
|
||||
{ |
|
||||
public: |
|
||||
/* When assoc_container_factory_class<Container> is an MPL placeholder
|
|
||||
* expression, referring to Container::iterator and Container::value_type |
|
||||
* force the MPL placeholder expression Container to be instantiated, which |
|
||||
* is wasteful and can fail in concept-checked STL implementations. |
|
||||
* We protect ourselves against this circumstance. |
|
||||
*/ |
|
||||
|
|
||||
typedef typename detail::nested_iterator_if_not_placeholder_expression< |
|
||||
Container |
|
||||
>::type handle_type; |
|
||||
typedef typename detail::nested_value_type_if_not_placeholder_expression< |
|
||||
Container |
|
||||
>::type entry_type; |
|
||||
|
|
||||
handle_type insert(const entry_type& x) |
|
||||
{ |
|
||||
return cont.insert(x).first; |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
handle_type insert(entry_type&& x) |
|
||||
{ |
|
||||
return cont.insert(std::move(x)).first; |
|
||||
} |
|
||||
#endif
|
|
||||
|
|
||||
void erase(handle_type h) |
|
||||
{ |
|
||||
cont.erase(h); |
|
||||
} |
|
||||
|
|
||||
static const entry_type& entry(handle_type h){return *h;} |
|
||||
|
|
||||
private: |
|
||||
/* As above, avoid instantiating Container if it is an
|
|
||||
* MPL placeholder expression. |
|
||||
*/ |
|
||||
|
|
||||
typedef typename mpl::if_< |
|
||||
detail::is_placeholder_expression<Container>, |
|
||||
int, |
|
||||
Container |
|
||||
>::type container_type; |
|
||||
container_type cont; |
|
||||
|
|
||||
public: |
|
||||
typedef assoc_container_factory_class type; |
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,assoc_container_factory_class,(Container)) |
|
||||
}; |
|
||||
|
|
||||
/* assoc_container_factory_class specifier */ |
|
||||
|
|
||||
template< |
|
||||
typename ContainerSpecifier |
|
||||
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF |
|
||||
> |
|
||||
struct assoc_container_factory:factory_marker |
|
||||
{ |
|
||||
template<typename Entry,typename Key> |
|
||||
struct apply |
|
||||
{ |
|
||||
typedef assoc_container_factory_class< |
|
||||
typename mpl::apply2<ContainerSpecifier,Entry,Key>::type |
|
||||
> type; |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,35 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_FWD_HPP
|
|
||||
#define BOOST_FLYWEIGHT_ASSOC_CONTAINER_FACTORY_FWD_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/flyweight/detail/not_placeholder_expr.hpp>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template<typename Container> |
|
||||
class assoc_container_factory_class; |
|
||||
|
|
||||
template< |
|
||||
typename ContainerSpecifier |
|
||||
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION |
|
||||
> |
|
||||
struct assoc_container_factory; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,79 +0,0 @@ |
|||||
/* Copyright 2006-2020 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
|
||||
#define BOOST_FLYWEIGHT_DETAIL_ARCHIVE_CONSTRUCTED_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
|
||||
#include <boost/noncopyable.hpp>
|
|
||||
#include <boost/core/serialization.hpp>
|
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
namespace detail{ |
|
||||
|
|
||||
/* constructs a stack-based object from a serialization archive */ |
|
||||
|
|
||||
template<typename T> |
|
||||
struct archive_constructed:private noncopyable |
|
||||
{ |
|
||||
template<class Archive> |
|
||||
archive_constructed(Archive& ar,const unsigned int version) |
|
||||
{ |
|
||||
core::load_construct_data_adl(ar,&get(),version); |
|
||||
BOOST_TRY{ |
|
||||
ar>>get(); |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
(&get())->~T(); |
|
||||
BOOST_RETHROW; |
|
||||
} |
|
||||
BOOST_CATCH_END |
|
||||
} |
|
||||
|
|
||||
template<class Archive> |
|
||||
archive_constructed(const char* name,Archive& ar,const unsigned int version) |
|
||||
{ |
|
||||
core::load_construct_data_adl(ar,&get(),version); |
|
||||
BOOST_TRY{ |
|
||||
ar>>serialization::make_nvp(name,get()); |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
(&get())->~T(); |
|
||||
BOOST_RETHROW; |
|
||||
} |
|
||||
BOOST_CATCH_END |
|
||||
} |
|
||||
|
|
||||
~archive_constructed() |
|
||||
{ |
|
||||
(&get())->~T(); |
|
||||
} |
|
||||
|
|
||||
T& get(){return *static_cast<T*>(static_cast<void*>(&space));} |
|
||||
|
|
||||
private: |
|
||||
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights::detail */ |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,65 +0,0 @@ |
|||||
/* Copyright 2006-2009 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_DETAIL_IS_PLACEHOLDER_EXPR_HPP
|
|
||||
#define BOOST_FLYWEIGHT_DETAIL_IS_PLACEHOLDER_EXPR_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/type_traits/is_same.hpp>
|
|
||||
#include <boost/mpl/apply.hpp>
|
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
|
||||
#include <boost/mpl/not.hpp>
|
|
||||
#include <boost/preprocessor/facilities/intercept.hpp>
|
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
namespace detail{ |
|
||||
|
|
||||
/* is_placeholder_expression<T> indicates whether T is an
|
|
||||
* MPL placeholder expression. |
|
||||
*/ |
|
||||
|
|
||||
template<typename T> |
|
||||
struct is_placeholder_expression_helper |
|
||||
{ |
|
||||
template< |
|
||||
BOOST_PP_ENUM_PARAMS( |
|
||||
BOOST_MPL_LIMIT_METAFUNCTION_ARITY,typename BOOST_PP_INTERCEPT) |
|
||||
> |
|
||||
struct apply{ |
|
||||
typedef int type; |
|
||||
}; |
|
||||
|
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_placeholder_expression_helper,(T)) |
|
||||
}; |
|
||||
|
|
||||
template<typename T> |
|
||||
struct is_placeholder_expression: |
|
||||
mpl::not_<is_same< |
|
||||
typename mpl::apply< |
|
||||
is_placeholder_expression_helper<T>, |
|
||||
BOOST_PP_ENUM_PARAMS( |
|
||||
BOOST_MPL_LIMIT_METAFUNCTION_ARITY,int BOOST_PP_INTERCEPT) |
|
||||
>::type, |
|
||||
int |
|
||||
> > |
|
||||
{}; |
|
||||
|
|
||||
} /* namespace flyweights::detail */ |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,39 +0,0 @@ |
|||||
/* Copyright 2006-2009 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_DETAIL_NESTED_XXX_IF_NOT_PH_HPP
|
|
||||
#define BOOST_FLYWEIGHT_DETAIL_NESTED_XXX_IF_NOT_PH_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/flyweight/detail/is_placeholder_expr.hpp>
|
|
||||
#include <boost/mpl/if.hpp>
|
|
||||
|
|
||||
/* nested_##name##_if_not_placeholder_expression<T>::type is T::name unless
|
|
||||
* T is an MPL placeholder expression, in which case it defaults to int. |
|
||||
*/ |
|
||||
|
|
||||
#define BOOST_FLYWEIGHT_NESTED_XXX_IF_NOT_PLACEHOLDER_EXPRESSION_DEF(name) \
|
|
||||
struct nested_##name##_if_not_placeholder_expression_helper \ |
|
||||
{ \ |
|
||||
typedef int name; \ |
|
||||
}; \ |
|
||||
\ |
|
||||
template<typename T> \ |
|
||||
struct nested_##name##_if_not_placeholder_expression \ |
|
||||
{ \ |
|
||||
typedef typename boost::mpl::if_< \ |
|
||||
boost::flyweights::detail::is_placeholder_expression<T>, \ |
|
||||
nested_##name##_if_not_placeholder_expression_helper, \ |
|
||||
T \ |
|
||||
>::type::name type; \ |
|
||||
}; |
|
||||
|
|
||||
#endif
|
|
@ -1,98 +0,0 @@ |
|||||
/* Copyright 2006-2014 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_DETAIL_SERIALIZATION_HELPER_HPP
|
|
||||
#define BOOST_FLYWEIGHT_DETAIL_SERIALIZATION_HELPER_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/multi_index_container.hpp>
|
|
||||
#include <boost/multi_index/hashed_index.hpp>
|
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
|
||||
#include <boost/noncopyable.hpp>
|
|
||||
#include <vector>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
namespace detail{ |
|
||||
|
|
||||
/* The serialization helpers for flyweight<T> map numerical IDs to
|
|
||||
* flyweight exemplars --an exemplar is the flyweight object |
|
||||
* associated to a given value that appears first on the serialization |
|
||||
* stream, so that subsequent equivalent flyweight objects will be made |
|
||||
* to refer to it during the serialization process. |
|
||||
*/ |
|
||||
|
|
||||
template<typename Flyweight> |
|
||||
struct flyweight_value_address |
|
||||
{ |
|
||||
typedef const typename Flyweight::value_type* result_type; |
|
||||
|
|
||||
result_type operator()(const Flyweight& x)const{return &x.get();} |
|
||||
}; |
|
||||
|
|
||||
template<typename Flyweight> |
|
||||
class save_helper:private noncopyable |
|
||||
{ |
|
||||
typedef multi_index::multi_index_container< |
|
||||
Flyweight, |
|
||||
multi_index::indexed_by< |
|
||||
multi_index::random_access<>, |
|
||||
multi_index::hashed_unique<flyweight_value_address<Flyweight> > |
|
||||
> |
|
||||
> table; |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
typedef typename table::size_type size_type; |
|
||||
|
|
||||
size_type size()const{return t.size();} |
|
||||
|
|
||||
size_type find(const Flyweight& x)const |
|
||||
{ |
|
||||
return multi_index::project<0>(t,multi_index::get<1>(t).find(&x.get())) |
|
||||
-t.begin(); |
|
||||
} |
|
||||
|
|
||||
void push_back(const Flyweight& x){t.push_back(x);} |
|
||||
|
|
||||
private: |
|
||||
table t; |
|
||||
}; |
|
||||
|
|
||||
template<typename Flyweight> |
|
||||
class load_helper:private noncopyable |
|
||||
{ |
|
||||
typedef std::vector<Flyweight> table; |
|
||||
|
|
||||
public: |
|
||||
|
|
||||
typedef typename table::size_type size_type; |
|
||||
|
|
||||
size_type size()const{return t.size();} |
|
||||
|
|
||||
Flyweight operator[](size_type n)const{return t[n];} |
|
||||
|
|
||||
void push_back(const Flyweight& x){t.push_back(x);} |
|
||||
|
|
||||
private: |
|
||||
table t; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights::detail */ |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,54 +0,0 @@ |
|||||
/* Copyright 2006-2011 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_INTERMODULE_HOLDER_HPP
|
|
||||
#define BOOST_FLYWEIGHT_INTERMODULE_HOLDER_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/holder_tag.hpp>
|
|
||||
#include <boost/flyweight/intermodule_holder_fwd.hpp>
|
|
||||
#include <boost/interprocess/detail/intermodule_singleton.hpp>
|
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
|
||||
|
|
||||
/* intermodule_holder_class guarantees a unique instance across all dynamic
|
|
||||
* modules of a program. |
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template<typename C> |
|
||||
struct intermodule_holder_class: |
|
||||
interprocess::ipcdetail::intermodule_singleton<C,true>, |
|
||||
holder_marker |
|
||||
{ |
|
||||
typedef intermodule_holder_class type; |
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,intermodule_holder_class,(C)) |
|
||||
}; |
|
||||
|
|
||||
/* intermodule_holder_class specifier */ |
|
||||
|
|
||||
struct intermodule_holder:holder_marker |
|
||||
{ |
|
||||
template<typename C> |
|
||||
struct apply |
|
||||
{ |
|
||||
typedef intermodule_holder_class<C> type; |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,29 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_INTERMODULE_HOLDER_FWD_HPP
|
|
||||
#define BOOST_FLYWEIGHT_INTERMODULE_HOLDER_FWD_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template<typename C> |
|
||||
struct intermodule_holder_class; |
|
||||
|
|
||||
struct intermodule_holder; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,301 +0,0 @@ |
|||||
/* Copyright 2006-2018 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_KEY_VALUE_HPP
|
|
||||
#define BOOST_FLYWEIGHT_KEY_VALUE_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/detail/workaround.hpp>
|
|
||||
#include <boost/flyweight/detail/perfect_fwd.hpp>
|
|
||||
#include <boost/flyweight/detail/value_tag.hpp>
|
|
||||
#include <boost/flyweight/key_value_fwd.hpp>
|
|
||||
#include <boost/mpl/assert.hpp>
|
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
|
||||
#include <boost/type_traits/is_same.hpp>
|
|
||||
#include <new>
|
|
||||
|
|
||||
/* key-value policy: flywewight lookup is based on Key, which also serves
|
|
||||
* to construct Value only when needed (new factory entry). key_value is |
|
||||
* used to avoid the construction of temporary values when such construction |
|
||||
* is expensive. |
|
||||
* Optionally, KeyFromValue extracts the key from a value, which |
|
||||
* is needed in expressions like this: |
|
||||
* |
|
||||
* typedef flyweight<key_value<Key,Value> > fw_t; |
|
||||
* fw_t fw; |
|
||||
* Value v; |
|
||||
* fw=v; // no key explicitly given
|
|
||||
* |
|
||||
* If no KeyFromValue is provided, this latter expression fails to compile. |
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
namespace detail{ |
|
||||
|
|
||||
template<typename Key,typename Value,typename KeyFromValue> |
|
||||
struct optimized_key_value:value_marker |
|
||||
{ |
|
||||
typedef Key key_type; |
|
||||
typedef Value value_type; |
|
||||
|
|
||||
class rep_type |
|
||||
{ |
|
||||
public: |
|
||||
/* template ctors */ |
|
||||
|
|
||||
#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
|
|
||||
:value_ptr(0) \ |
|
||||
{ \ |
|
||||
new(spc_ptr())key_type(BOOST_FLYWEIGHT_FORWARD(args)); \ |
|
||||
} |
|
||||
|
|
||||
BOOST_FLYWEIGHT_PERFECT_FWD( |
|
||||
explicit rep_type, |
|
||||
BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY) |
|
||||
|
|
||||
#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY
|
|
||||
|
|
||||
rep_type(const rep_type& x):value_ptr(x.value_ptr) |
|
||||
{ |
|
||||
if(!x.value_ptr)new(key_ptr())key_type(*x.key_ptr()); |
|
||||
} |
|
||||
|
|
||||
rep_type(const value_type& x):value_ptr(&x){} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
rep_type(rep_type&& x):value_ptr(x.value_ptr) |
|
||||
{ |
|
||||
if(!x.value_ptr)new(key_ptr())key_type(std::move(*x.key_ptr())); |
|
||||
} |
|
||||
|
|
||||
rep_type(value_type&& x):value_ptr(&x){} |
|
||||
#endif
|
|
||||
|
|
||||
~rep_type() |
|
||||
{ |
|
||||
if(!value_ptr) key_ptr()->~key_type(); |
|
||||
else if(value_cted())value_ptr->~value_type(); |
|
||||
} |
|
||||
|
|
||||
operator const key_type&()const |
|
||||
{ |
|
||||
if(value_ptr)return key_from_value(*value_ptr); |
|
||||
else return *key_ptr(); |
|
||||
} |
|
||||
|
|
||||
operator const value_type&()const |
|
||||
{ |
|
||||
/* This is always called after construct_value() or copy_value(),
|
|
||||
* so we access spc directly rather than through value_ptr to |
|
||||
* save us an indirection. |
|
||||
*/ |
|
||||
|
|
||||
return *static_cast<value_type*>(spc_ptr()); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
friend struct optimized_key_value; |
|
||||
|
|
||||
void* spc_ptr()const{return static_cast<void*>(&spc);} |
|
||||
bool value_cted()const{return value_ptr==spc_ptr();} |
|
||||
|
|
||||
key_type* key_ptr()const |
|
||||
{ |
|
||||
return static_cast<key_type*>(static_cast<void*>(&spc)); |
|
||||
} |
|
||||
|
|
||||
static const key_type& key_from_value(const value_type& x) |
|
||||
{ |
|
||||
KeyFromValue k; |
|
||||
return k(x); |
|
||||
} |
|
||||
|
|
||||
void construct_value()const |
|
||||
{ |
|
||||
if(!value_cted()){ |
|
||||
/* value_ptr must be ==0, oherwise copy_value would have been called */ |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
key_type k(std::move(*key_ptr())); |
|
||||
#else
|
|
||||
key_type k(*key_ptr()); |
|
||||
#endif
|
|
||||
|
|
||||
key_ptr()->~key_type(); |
|
||||
value_ptr= /* guarantees key won't be re-dted at ~rep_type if the */ |
|
||||
static_cast<value_type*>(spc_ptr())+1; /* next statement throws */ |
|
||||
value_ptr=new(spc_ptr())value_type(k); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void copy_value()const |
|
||||
{ |
|
||||
if(!value_cted())value_ptr=new(spc_ptr())value_type(*value_ptr); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
void move_value()const |
|
||||
{ |
|
||||
if(!value_cted())value_ptr= |
|
||||
new(spc_ptr())value_type(std::move(const_cast<value_type&>(*value_ptr))); |
|
||||
} |
|
||||
#endif
|
|
||||
|
|
||||
mutable typename boost::aligned_storage< |
|
||||
(sizeof(key_type)>sizeof(value_type))? |
|
||||
sizeof(key_type):sizeof(value_type), |
|
||||
(boost::alignment_of<key_type>::value > |
|
||||
boost::alignment_of<value_type>::value)? |
|
||||
boost::alignment_of<key_type>::value: |
|
||||
boost::alignment_of<value_type>::value |
|
||||
>::type spc; |
|
||||
mutable const value_type* value_ptr; |
|
||||
}; |
|
||||
|
|
||||
static void construct_value(const rep_type& r) |
|
||||
{ |
|
||||
r.construct_value(); |
|
||||
} |
|
||||
|
|
||||
static void copy_value(const rep_type& r) |
|
||||
{ |
|
||||
r.copy_value(); |
|
||||
} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
static void move_value(const rep_type& r) |
|
||||
{ |
|
||||
r.move_value(); |
|
||||
} |
|
||||
#endif
|
|
||||
}; |
|
||||
|
|
||||
template<typename Key,typename Value> |
|
||||
struct regular_key_value:value_marker |
|
||||
{ |
|
||||
typedef Key key_type; |
|
||||
typedef Value value_type; |
|
||||
|
|
||||
class rep_type |
|
||||
{ |
|
||||
public: |
|
||||
/* template ctors */ |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)&&\
|
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)&&\ |
|
||||
BOOST_WORKAROUND(__GNUC__,<=4)&&(__GNUC__<4||__GNUC_MINOR__<=4) |
|
||||
|
|
||||
/* GCC 4.4.2 (and probably prior) bug: the default ctor generated by the
|
|
||||
* variadic temmplate ctor below fails to value-initialize key. |
|
||||
*/ |
|
||||
|
|
||||
rep_type():key(),value_ptr(0){} |
|
||||
#endif
|
|
||||
|
|
||||
#define BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY(args) \
|
|
||||
:key(BOOST_FLYWEIGHT_FORWARD(args)),value_ptr(0){} |
|
||||
|
|
||||
BOOST_FLYWEIGHT_PERFECT_FWD( |
|
||||
explicit rep_type, |
|
||||
BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY) |
|
||||
|
|
||||
#undef BOOST_FLYWEIGHT_PERFECT_FWD_CTR_BODY
|
|
||||
|
|
||||
rep_type(const rep_type& x):key(x.key),value_ptr(0){} |
|
||||
rep_type(const value_type&):key(no_key_from_value_failure()){} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
rep_type(rep_type&& x):key(std::move(x.key)),value_ptr(0){} |
|
||||
rep_type(value_type&&):key(no_key_from_value_failure()){} |
|
||||
#endif
|
|
||||
|
|
||||
~rep_type() |
|
||||
{ |
|
||||
if(value_ptr)value_ptr->~value_type(); |
|
||||
} |
|
||||
|
|
||||
operator const key_type&()const{return key;} |
|
||||
|
|
||||
operator const value_type&()const |
|
||||
{ |
|
||||
/* This is always called after construct_value(),so we access spc
|
|
||||
* directly rather than through value_ptr to save us an indirection. |
|
||||
*/ |
|
||||
|
|
||||
return *static_cast<value_type*>(spc_ptr()); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
friend struct regular_key_value; |
|
||||
|
|
||||
void* spc_ptr()const{return static_cast<void*>(&spc);} |
|
||||
|
|
||||
struct no_key_from_value_failure |
|
||||
{ |
|
||||
BOOST_MPL_ASSERT_MSG( |
|
||||
false, |
|
||||
NO_KEY_FROM_VALUE_CONVERSION_PROVIDED, |
|
||||
(key_type,value_type)); |
|
||||
|
|
||||
operator const key_type&()const; |
|
||||
}; |
|
||||
|
|
||||
void construct_value()const |
|
||||
{ |
|
||||
if(!value_ptr)value_ptr=new(spc_ptr())value_type(key); |
|
||||
} |
|
||||
|
|
||||
key_type key; |
|
||||
mutable typename boost::aligned_storage< |
|
||||
sizeof(value_type), |
|
||||
boost::alignment_of<value_type>::value |
|
||||
>::type spc; |
|
||||
mutable const value_type* value_ptr; |
|
||||
}; |
|
||||
|
|
||||
static void construct_value(const rep_type& r) |
|
||||
{ |
|
||||
r.construct_value(); |
|
||||
} |
|
||||
|
|
||||
/* copy_value() and move_value() can't really ever be called, provided to avoid
|
|
||||
* compile errors (it is the no_key_from_value_failure compile error we want to |
|
||||
* appear in these cases). |
|
||||
*/ |
|
||||
|
|
||||
static void copy_value(const rep_type&){} |
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||
static void move_value(const rep_type&){} |
|
||||
#endif
|
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights::detail */ |
|
||||
|
|
||||
template<typename Key,typename Value,typename KeyFromValue> |
|
||||
struct key_value: |
|
||||
mpl::if_< |
|
||||
is_same<KeyFromValue,no_key_from_value>, |
|
||||
detail::regular_key_value<Key,Value>, |
|
||||
detail::optimized_key_value<Key,Value,KeyFromValue> |
|
||||
>::type |
|
||||
{}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,29 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_KEY_VALUE_FWD_HPP
|
|
||||
#define BOOST_FLYWEIGHT_KEY_VALUE_FWD_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
struct no_key_from_value; |
|
||||
|
|
||||
template<typename Key,typename Value,typename KeyFromValue=no_key_from_value> |
|
||||
struct key_value; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,36 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_NO_LOCKING_HPP
|
|
||||
#define BOOST_FLYWEIGHT_NO_LOCKING_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/no_locking_fwd.hpp>
|
|
||||
#include <boost/flyweight/locking_tag.hpp>
|
|
||||
|
|
||||
/* null locking policy */ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
struct no_locking:locking_marker |
|
||||
{ |
|
||||
struct mutex_type{}; |
|
||||
typedef mutex_type lock_type; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,46 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_NO_TRACKING_HPP
|
|
||||
#define BOOST_FLYWEIGHT_NO_TRACKING_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/no_tracking_fwd.hpp>
|
|
||||
#include <boost/flyweight/tracking_tag.hpp>
|
|
||||
|
|
||||
/* Null tracking policy: elements are never erased from the factory.
|
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
struct no_tracking:tracking_marker |
|
||||
{ |
|
||||
struct entry_type |
|
||||
{ |
|
||||
template<typename Value,typename Key> |
|
||||
struct apply{typedef Value type;}; |
|
||||
}; |
|
||||
|
|
||||
struct handle_type |
|
||||
{ |
|
||||
template<typename Handle,typename TrackingHelper> |
|
||||
struct apply{typedef Handle type;}; |
|
||||
}; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,26 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_NO_TRACKING_FWD_HPP
|
|
||||
#define BOOST_FLYWEIGHT_NO_TRACKING_FWD_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
struct no_tracking; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,97 +0,0 @@ |
|||||
/* Copyright 2006-2023 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_SERIALIZE_HPP
|
|
||||
#define BOOST_FLYWEIGHT_SERIALIZE_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/flyweight_fwd.hpp>
|
|
||||
#include <boost/flyweight/detail/archive_constructed.hpp>
|
|
||||
#include <boost/flyweight/detail/serialization_helper.hpp>
|
|
||||
#include <boost/core/serialization.hpp>
|
|
||||
#include <boost/throw_exception.hpp>
|
|
||||
#include <memory>
|
|
||||
#include <stdexcept>
|
|
||||
|
|
||||
/* Serialization routines for flyweight<T>.
|
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template< |
|
||||
class Archive, |
|
||||
typename T,typename Arg1,typename Arg2,typename Arg3 |
|
||||
> |
|
||||
inline void serialize( |
|
||||
Archive& ar,::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f, |
|
||||
const unsigned int version) |
|
||||
{ |
|
||||
core::split_free(ar,f,version); |
|
||||
} |
|
||||
|
|
||||
template< |
|
||||
class Archive, |
|
||||
typename T,typename Arg1,typename Arg2,typename Arg3 |
|
||||
> |
|
||||
void save( |
|
||||
Archive& ar,const ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f, |
|
||||
const unsigned int /*version*/) |
|
||||
{ |
|
||||
typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight; |
|
||||
typedef ::boost::flyweights::detail::save_helper<flyweight> helper; |
|
||||
typedef typename helper::size_type size_type; |
|
||||
|
|
||||
helper& hlp=ar.template get_helper<helper>(); |
|
||||
|
|
||||
size_type n=hlp.find(f); |
|
||||
ar<<make_nvp("item",n); |
|
||||
if(n==hlp.size()){ |
|
||||
ar<<make_nvp("key",f.get_key()); |
|
||||
hlp.push_back(f); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template< |
|
||||
class Archive, |
|
||||
typename T,typename Arg1,typename Arg2,typename Arg3 |
|
||||
> |
|
||||
void load( |
|
||||
Archive& ar,::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f, |
|
||||
const unsigned int version) |
|
||||
{ |
|
||||
typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight; |
|
||||
typedef typename flyweight::key_type key_type; |
|
||||
typedef ::boost::flyweights::detail::load_helper<flyweight> helper; |
|
||||
typedef typename helper::size_type size_type; |
|
||||
|
|
||||
helper& hlp=ar.template get_helper<helper>(); |
|
||||
|
|
||||
size_type n=0; |
|
||||
ar>>make_nvp("item",n); |
|
||||
if(n>hlp.size()){ |
|
||||
throw_exception(std::runtime_error("Invalid or corrupted archive")); |
|
||||
} |
|
||||
else if(n==hlp.size()){ |
|
||||
::boost::flyweights::detail::archive_constructed<key_type> k( |
|
||||
"key",ar,version); |
|
||||
hlp.push_back(flyweight(k.get())); |
|
||||
} |
|
||||
f=hlp[n]; |
|
||||
} |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,82 +0,0 @@ |
|||||
/* Copyright 2006-2009 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_SET_FACTORY_HPP
|
|
||||
#define BOOST_FLYWEIGHT_SET_FACTORY_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/detail/allocator_utilities.hpp>
|
|
||||
#include <boost/flyweight/assoc_container_factory.hpp>
|
|
||||
#include <boost/flyweight/factory_tag.hpp>
|
|
||||
#include <boost/flyweight/set_factory_fwd.hpp>
|
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
|
||||
#include <boost/mpl/if.hpp>
|
|
||||
#include <set>
|
|
||||
|
|
||||
/* Particularization of assoc_container_factory_class using a set.
|
|
||||
*/ |
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template< |
|
||||
typename Entry,typename Key, |
|
||||
typename Compare,typename Allocator |
|
||||
> |
|
||||
class set_factory_class: |
|
||||
public assoc_container_factory_class< |
|
||||
std::set< |
|
||||
Entry, |
|
||||
typename boost::mpl::if_< |
|
||||
mpl::is_na<Compare>, |
|
||||
std::less<Key>, |
|
||||
Compare |
|
||||
>::type, |
|
||||
typename boost::mpl::if_< |
|
||||
mpl::is_na<Allocator>, |
|
||||
std::allocator<Entry>, |
|
||||
Allocator |
|
||||
>::type |
|
||||
> |
|
||||
> |
|
||||
{ |
|
||||
public: |
|
||||
typedef set_factory_class type; |
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT( |
|
||||
4,set_factory_class,(Entry,Key,Compare,Allocator)) |
|
||||
}; |
|
||||
|
|
||||
/* set_factory_class specifier */ |
|
||||
|
|
||||
template< |
|
||||
typename Compare,typename Allocator |
|
||||
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION_DEF |
|
||||
> |
|
||||
struct set_factory:factory_marker |
|
||||
{ |
|
||||
template<typename Entry,typename Key> |
|
||||
struct apply: |
|
||||
mpl::apply2< |
|
||||
set_factory_class< |
|
||||
boost::mpl::_1,boost::mpl::_2,Compare,Allocator |
|
||||
>, |
|
||||
Entry,Key |
|
||||
> |
|
||||
{}; |
|
||||
}; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,40 +0,0 @@ |
|||||
/* Copyright 2006-2008 Joaquin M Lopez Munoz.
|
|
||||
* 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 http://www.boost.org/libs/flyweight for library home page.
|
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_FLYWEIGHT_SET_FACTORY_FWD_HPP
|
|
||||
#define BOOST_FLYWEIGHT_SET_FACTORY_FWD_HPP
|
|
||||
|
|
||||
#if defined(_MSC_VER)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
|
|
||||
#include <boost/flyweight/detail/not_placeholder_expr.hpp>
|
|
||||
#include <boost/mpl/aux_/na.hpp>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
|
|
||||
namespace flyweights{ |
|
||||
|
|
||||
template< |
|
||||
typename Entry,typename Key, |
|
||||
typename Compare=mpl::na,typename Allocator=mpl::na |
|
||||
> |
|
||||
class set_factory_class; |
|
||||
|
|
||||
template< |
|
||||
typename Compare=mpl::na,typename Allocator=mpl::na |
|
||||
BOOST_FLYWEIGHT_NOT_A_PLACEHOLDER_EXPRESSION |
|
||||
> |
|
||||
struct set_factory; |
|
||||
|
|
||||
} /* namespace flyweights */ |
|
||||
|
|
||||
} /* namespace boost */ |
|
||||
|
|
||||
#endif
|
|
@ -1,580 +0,0 @@ |
|||||
// (C) Copyright Jeremy William Murphy 2016.
|
|
||||
|
|
||||
// Use, modification and distribution are subject to the
|
|
||||
// Boost Software License, Version 1.0. (See accompanying file
|
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
|
||||
|
|
||||
#ifndef BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
|
||||
#define BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
|
||||
|
|
||||
#include <boost/assert.hpp>
|
|
||||
#include <boost/core/enable_if.hpp>
|
|
||||
|
|
||||
#include <boost/config.hpp> // for BOOST_NESTED_TEMPLATE, etc.
|
|
||||
#include <boost/limits.hpp> // for std::numeric_limits
|
|
||||
#include <climits> // for CHAR_MIN
|
|
||||
#include <boost/detail/workaround.hpp>
|
|
||||
#include <iterator>
|
|
||||
#include <algorithm>
|
|
||||
#include <limits>
|
|
||||
#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
|
|
||||
#include <type_traits>
|
|
||||
#endif
|
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
|
||||
#include <functional>
|
|
||||
#endif
|
|
||||
|
|
||||
#if ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
|
||||
#include <intrin.h>
|
|
||||
#endif
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
#pragma warning(push)
|
|
||||
#pragma warning(disable:4127 4244) // Conditional expression is constant
|
|
||||
#endif
|
|
||||
|
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_CXX11_NOEXCEPT)
|
|
||||
#define BOOST_GCD_NOEXCEPT(T) noexcept(std::is_arithmetic<T>::value)
|
|
||||
#else
|
|
||||
#define BOOST_GCD_NOEXCEPT(T)
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { |
|
||||
|
|
||||
template <class I> |
|
||||
class rational; |
|
||||
|
|
||||
namespace integer { |
|
||||
|
|
||||
namespace gcd_detail{ |
|
||||
|
|
||||
//
|
|
||||
// some helper functions which really should be constexpr already, but sadly aren't:
|
|
||||
//
|
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
|
||||
template <class T> |
|
||||
inline constexpr T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return a < b ? a : b; |
|
||||
} |
|
||||
template <class T> |
|
||||
inline constexpr auto constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) -> decltype(a.swap(b)) |
|
||||
{ |
|
||||
return a.swap(b); |
|
||||
} |
|
||||
template <class T, class U> |
|
||||
inline constexpr void constexpr_swap(T&a, U& b...) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
T t(static_cast<T&&>(a)); |
|
||||
a = static_cast<T&&>(b); |
|
||||
b = static_cast<T&&>(t); |
|
||||
} |
|
||||
#else
|
|
||||
template <class T> |
|
||||
inline T constexpr_min(T const& a, T const& b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return a < b ? a : b; |
|
||||
} |
|
||||
template <class T> |
|
||||
inline void constexpr_swap(T&a, T& b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
using std::swap; |
|
||||
swap(a, b); |
|
||||
} |
|
||||
#endif
|
|
||||
|
|
||||
template <class T, bool a = |
|
||||
#ifndef BOOST_NO_CXX11_HDR_TYPE_TRAITS
|
|
||||
std::is_unsigned<T>::value || |
|
||||
#endif
|
|
||||
(std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_signed)> |
|
||||
struct gcd_traits_abs_defaults |
|
||||
{ |
|
||||
inline static BOOST_CXX14_CONSTEXPR const T& abs(const T& val) BOOST_GCD_NOEXCEPT(T) { return val; } |
|
||||
}; |
|
||||
template <class T> |
|
||||
struct gcd_traits_abs_defaults<T, false> |
|
||||
{ |
|
||||
inline static T BOOST_CXX14_CONSTEXPR abs(const T& val) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
// This sucks, but std::abs is not constexpr :(
|
|
||||
return val < T(0) ? -val : val; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
enum method_type |
|
||||
{ |
|
||||
method_euclid = 0, |
|
||||
method_binary = 1, |
|
||||
method_mixed = 2 |
|
||||
}; |
|
||||
|
|
||||
struct any_convert |
|
||||
{ |
|
||||
template <class T> |
|
||||
any_convert(const T&); |
|
||||
}; |
|
||||
|
|
||||
struct unlikely_size |
|
||||
{ |
|
||||
char buf[9973]; |
|
||||
}; |
|
||||
|
|
||||
unlikely_size operator <<= (any_convert, any_convert); |
|
||||
unlikely_size operator >>= (any_convert, any_convert); |
|
||||
|
|
||||
template <class T> |
|
||||
struct gcd_traits_defaults : public gcd_traits_abs_defaults<T> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(T& val) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
unsigned r = 0; |
|
||||
while (T(0) == (val & 1u)) |
|
||||
{ |
|
||||
#ifdef _MSC_VER // VC++ can't handle operator >>= in constexpr code for some reason
|
|
||||
val = val >> 1; |
|
||||
#else
|
|
||||
val >>= 1; |
|
||||
#endif
|
|
||||
++r; |
|
||||
} |
|
||||
return r; |
|
||||
} |
|
||||
inline static BOOST_CXX14_CONSTEXPR bool less(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return a < b; |
|
||||
} |
|
||||
|
|
||||
static T& get_value(); |
|
||||
|
|
||||
#ifndef BOOST_NO_SFINAE
|
|
||||
static const bool has_operator_left_shift_equal = sizeof(get_value() <<= 2) != sizeof(unlikely_size); |
|
||||
static const bool has_operator_right_shift_equal = sizeof(get_value() >>= 2) != sizeof(unlikely_size); |
|
||||
#else
|
|
||||
static const bool has_operator_left_shift_equal = true; |
|
||||
static const bool has_operator_right_shift_equal = true; |
|
||||
#endif
|
|
||||
static const method_type method = std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::is_integer && has_operator_left_shift_equal && has_operator_right_shift_equal ? method_mixed : method_euclid; |
|
||||
}; |
|
||||
//
|
|
||||
// Default gcd_traits just inherits from defaults:
|
|
||||
//
|
|
||||
template <class T> |
|
||||
struct gcd_traits : public gcd_traits_defaults<T> {}; |
|
||||
|
|
||||
//
|
|
||||
// Some platforms have fast bitscan operations, that allow us to implement
|
|
||||
// make_odd much more efficiently, unfortunately we can't use these if we want
|
|
||||
// the functions to be constexpr as the compiler intrinsics aren't constexpr.
|
|
||||
//
|
|
||||
#if defined(BOOST_NO_CXX14_CONSTEXPR) && ((defined(BOOST_MSVC) && (BOOST_MSVC >= 1600)) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64))
|
|
||||
#pragma intrinsic(_BitScanForward,)
|
|
||||
template <> |
|
||||
struct gcd_traits<unsigned long> : public gcd_traits_defaults<unsigned long> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static unsigned find_lsb(unsigned long val) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned long result; |
|
||||
_BitScanForward(&result, val); |
|
||||
return result; |
|
||||
} |
|
||||
BOOST_FORCEINLINE static unsigned make_odd(unsigned long& val) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned result = find_lsb(val); |
|
||||
val >>= result; |
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
#ifdef _M_X64
|
|
||||
#pragma intrinsic(_BitScanForward64)
|
|
||||
template <> |
|
||||
struct gcd_traits<unsigned __int64> : public gcd_traits_defaults<unsigned __int64> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static unsigned find_lsb(unsigned __int64 mask) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned long result; |
|
||||
_BitScanForward64(&result, mask); |
|
||||
return result; |
|
||||
} |
|
||||
BOOST_FORCEINLINE static unsigned make_odd(unsigned __int64& val) BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned result = find_lsb(val); |
|
||||
val >>= result; |
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
#endif
|
|
||||
//
|
|
||||
// Other integer type are trivial adaptations of the above,
|
|
||||
// this works for signed types too, as by the time these functions
|
|
||||
// are called, all values are > 0.
|
|
||||
//
|
|
||||
template <> struct gcd_traits<long> : public gcd_traits_defaults<long> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(long& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<unsigned int> : public gcd_traits_defaults<unsigned int> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<int> : public gcd_traits_defaults<int> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(int& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<unsigned short> : public gcd_traits_defaults<unsigned short> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<short> : public gcd_traits_defaults<short> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(short& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<unsigned char> : public gcd_traits_defaults<unsigned char> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<signed char> : public gcd_traits_defaults<signed char> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(signed char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
template <> struct gcd_traits<char> : public gcd_traits_defaults<char> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(char& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
|
||||
template <> struct gcd_traits<wchar_t> : public gcd_traits_defaults<wchar_t> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } }; |
|
||||
#endif
|
|
||||
#ifdef _M_X64
|
|
||||
template <> struct gcd_traits<__int64> : public gcd_traits_defaults<__int64> |
|
||||
{ BOOST_FORCEINLINE static unsigned make_odd(__int64& val)BOOST_NOEXCEPT{ unsigned result = gcd_traits<unsigned __int64>::find_lsb(val); val >>= result; return result; } }; |
|
||||
#endif
|
|
||||
|
|
||||
#elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__))
|
|
||||
|
|
||||
template <> |
|
||||
struct gcd_traits<unsigned> : public gcd_traits_defaults<unsigned> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned mask)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
return __builtin_ctz(mask); |
|
||||
} |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned& val)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned result = find_lsb(val); |
|
||||
val >>= result; |
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
template <> |
|
||||
struct gcd_traits<unsigned long> : public gcd_traits_defaults<unsigned long> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(unsigned long mask)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
return __builtin_ctzl(mask); |
|
||||
} |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned long& val)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned result = find_lsb(val); |
|
||||
val >>= result; |
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
template <> |
|
||||
struct gcd_traits<boost::ulong_long_type> : public gcd_traits_defaults<boost::ulong_long_type> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned find_lsb(boost::ulong_long_type mask)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
return __builtin_ctzll(mask); |
|
||||
} |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::ulong_long_type& val)BOOST_NOEXCEPT |
|
||||
{ |
|
||||
unsigned result = find_lsb(val); |
|
||||
val >>= result; |
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
//
|
|
||||
// Other integer type are trivial adaptations of the above,
|
|
||||
// this works for signed types too, as by the time these functions
|
|
||||
// are called, all values are > 0.
|
|
||||
//
|
|
||||
template <> struct gcd_traits<boost::long_long_type> : public gcd_traits_defaults<boost::long_long_type> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(boost::long_long_type& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<boost::ulong_long_type>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<long> : public gcd_traits_defaults<long> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(long& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<int> : public gcd_traits_defaults<int> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(int& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned long>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<unsigned short> : public gcd_traits_defaults<unsigned short> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<short> : public gcd_traits_defaults<short> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(short& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<unsigned char> : public gcd_traits_defaults<unsigned char> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(unsigned char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<signed char> : public gcd_traits_defaults<signed char> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(signed char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
template <> struct gcd_traits<char> : public gcd_traits_defaults<char> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(char& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
|
|
||||
template <> struct gcd_traits<wchar_t> : public gcd_traits_defaults<wchar_t> |
|
||||
{ |
|
||||
BOOST_FORCEINLINE static BOOST_CXX14_CONSTEXPR unsigned make_odd(wchar_t& val)BOOST_NOEXCEPT { unsigned result = gcd_traits<unsigned>::find_lsb(val); val >>= result; return result; } |
|
||||
}; |
|
||||
#endif
|
|
||||
#endif
|
|
||||
//
|
|
||||
// The Mixed Binary Euclid Algorithm
|
|
||||
// Sidi Mohamed Sedjelmaci
|
|
||||
// Electronic Notes in Discrete Mathematics 35 (2009) 169-176
|
|
||||
//
|
|
||||
template <class T> |
|
||||
BOOST_CXX14_CONSTEXPR T mixed_binary_gcd(T u, T v) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
if(gcd_traits<T>::less(u, v)) |
|
||||
constexpr_swap(u, v); |
|
||||
|
|
||||
unsigned shifts = 0; |
|
||||
|
|
||||
if(u == T(0)) |
|
||||
return v; |
|
||||
if(v == T(0)) |
|
||||
return u; |
|
||||
|
|
||||
shifts = constexpr_min(gcd_traits<T>::make_odd(u), gcd_traits<T>::make_odd(v)); |
|
||||
|
|
||||
while(gcd_traits<T>::less(1, v)) |
|
||||
{ |
|
||||
u %= v; |
|
||||
v -= u; |
|
||||
if(u == T(0)) |
|
||||
return v << shifts; |
|
||||
if(v == T(0)) |
|
||||
return u << shifts; |
|
||||
gcd_traits<T>::make_odd(u); |
|
||||
gcd_traits<T>::make_odd(v); |
|
||||
if(gcd_traits<T>::less(u, v)) |
|
||||
constexpr_swap(u, v); |
|
||||
} |
|
||||
return (v == 1 ? v : u) << shifts; |
|
||||
} |
|
||||
|
|
||||
/** Stein gcd (aka 'binary gcd')
|
|
||||
* |
|
||||
* From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose |
|
||||
*/ |
|
||||
template <typename SteinDomain> |
|
||||
BOOST_CXX14_CONSTEXPR SteinDomain Stein_gcd(SteinDomain m, SteinDomain n) BOOST_GCD_NOEXCEPT(SteinDomain) |
|
||||
{ |
|
||||
BOOST_ASSERT(m >= 0); |
|
||||
BOOST_ASSERT(n >= 0); |
|
||||
if (m == SteinDomain(0)) |
|
||||
return n; |
|
||||
if (n == SteinDomain(0)) |
|
||||
return m; |
|
||||
// m > 0 && n > 0
|
|
||||
unsigned d_m = gcd_traits<SteinDomain>::make_odd(m); |
|
||||
unsigned d_n = gcd_traits<SteinDomain>::make_odd(n); |
|
||||
// odd(m) && odd(n)
|
|
||||
while (m != n) |
|
||||
{ |
|
||||
if (n > m) |
|
||||
constexpr_swap(n, m); |
|
||||
m -= n; |
|
||||
gcd_traits<SteinDomain>::make_odd(m); |
|
||||
} |
|
||||
// m == n
|
|
||||
m <<= constexpr_min(d_m, d_n); |
|
||||
return m; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** Euclidean algorithm
|
|
||||
* |
|
||||
* From Mathematics to Generic Programming, Alexander Stepanov, Daniel Rose |
|
||||
* |
|
||||
*/ |
|
||||
template <typename EuclideanDomain> |
|
||||
inline BOOST_CXX14_CONSTEXPR EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) BOOST_GCD_NOEXCEPT(EuclideanDomain) |
|
||||
{ |
|
||||
while (b != EuclideanDomain(0)) |
|
||||
{ |
|
||||
a %= b; |
|
||||
constexpr_swap(a, b); |
|
||||
} |
|
||||
return a; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
template <typename T> |
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_mixed, T>::type |
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return gcd_detail::mixed_binary_gcd(a, b); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_binary, T>::type |
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return gcd_detail::Stein_gcd(a, b); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
inline BOOST_CXX14_CONSTEXPR BOOST_DEDUCED_TYPENAME enable_if_c<gcd_traits<T>::method == method_euclid, T>::type |
|
||||
optimal_gcd_select(T const &a, T const &b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
return gcd_detail::Euclid_gcd(a, b); |
|
||||
} |
|
||||
|
|
||||
template <class T> |
|
||||
inline BOOST_CXX14_CONSTEXPR T lcm_imp(const T& a, const T& b) BOOST_GCD_NOEXCEPT(T) |
|
||||
{ |
|
||||
T temp = boost::integer::gcd_detail::optimal_gcd_select(a, b); |
|
||||
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
|
|
||||
return (temp != T(0)) ? T(a / temp * b) : T(0); |
|
||||
#else
|
|
||||
return temp != T(0) ? T(a / temp * b) : T(0); |
|
||||
#endif
|
|
||||
} |
|
||||
|
|
||||
} // namespace detail
|
|
||||
|
|
||||
|
|
||||
template <typename Integer> |
|
||||
inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) |
|
||||
{ |
|
||||
if(a == (std::numeric_limits<Integer>::min)()) |
|
||||
return a == static_cast<Integer>(0) ? gcd_detail::gcd_traits<Integer>::abs(b) : boost::integer::gcd(static_cast<Integer>(a % b), b); |
|
||||
else if (b == (std::numeric_limits<Integer>::min)()) |
|
||||
return b == static_cast<Integer>(0) ? gcd_detail::gcd_traits<Integer>::abs(a) : boost::integer::gcd(a, static_cast<Integer>(b % a)); |
|
||||
return gcd_detail::optimal_gcd_select(static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(a)), static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(b))); |
|
||||
} |
|
||||
|
|
||||
template <typename Integer> |
|
||||
inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b) BOOST_GCD_NOEXCEPT(Integer) |
|
||||
{ |
|
||||
return gcd_detail::lcm_imp(static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(a)), static_cast<Integer>(gcd_detail::gcd_traits<Integer>::abs(b))); |
|
||||
} |
|
||||
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
|
|
||||
//
|
|
||||
// This looks slightly odd, but the variadic forms must have 3 or more arguments, and the variadic argument pack may be empty.
|
|
||||
// This matters not at all for most compilers, but Oracle C++ selects the wrong overload in the 2-arg case unless we do this.
|
|
||||
//
|
|
||||
template <typename Integer, typename... Args> |
|
||||
inline BOOST_CXX14_CONSTEXPR Integer gcd(Integer const &a, Integer const &b, const Integer& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) |
|
||||
{ |
|
||||
Integer t = gcd(b, c, args...); |
|
||||
return t == 1 ? 1 : gcd(a, t); |
|
||||
} |
|
||||
|
|
||||
template <typename Integer, typename... Args> |
|
||||
inline BOOST_CXX14_CONSTEXPR Integer lcm(Integer const &a, Integer const &b, Integer const& c, Args const&... args) BOOST_GCD_NOEXCEPT(Integer) |
|
||||
{ |
|
||||
return lcm(a, lcm(b, c, args...)); |
|
||||
} |
|
||||
#endif
|
|
||||
//
|
|
||||
// Special handling for rationals:
|
|
||||
//
|
|
||||
template <typename Integer> |
|
||||
inline typename boost::enable_if_c<std::numeric_limits<Integer>::is_specialized, boost::rational<Integer> >::type gcd(boost::rational<Integer> const &a, boost::rational<Integer> const &b) |
|
||||
{ |
|
||||
return boost::rational<Integer>(static_cast<Integer>(gcd(a.numerator(), b.numerator())), static_cast<Integer>(lcm(a.denominator(), b.denominator()))); |
|
||||
} |
|
||||
|
|
||||
template <typename Integer> |
|
||||
inline typename boost::enable_if_c<std::numeric_limits<Integer>::is_specialized, boost::rational<Integer> >::type lcm(boost::rational<Integer> const &a, boost::rational<Integer> const &b) |
|
||||
{ |
|
||||
return boost::rational<Integer>(static_cast<Integer>(lcm(a.numerator(), b.numerator())), static_cast<Integer>(gcd(a.denominator(), b.denominator()))); |
|
||||
} |
|
||||
/**
|
|
||||
* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 |
|
||||
* Chapter 4.5.2, Algorithm C: Greatest common divisor of n integers. |
|
||||
* |
|
||||
* Knuth counts down from n to zero but we naturally go from first to last. |
|
||||
* We also return the termination position because it might be useful to know. |
|
||||
* |
|
||||
* Partly by quirk, partly by design, this algorithm is defined for n = 1, |
|
||||
* because the gcd of {x} is x. It is not defined for n = 0. |
|
||||
* |
|
||||
* @tparam I Input iterator. |
|
||||
* @return The gcd of the range and the iterator position at termination. |
|
||||
*/ |
|
||||
template <typename I> |
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I> |
|
||||
gcd_range(I first, I last) BOOST_GCD_NOEXCEPT(I) |
|
||||
{ |
|
||||
BOOST_ASSERT(first != last); |
|
||||
typedef typename std::iterator_traits<I>::value_type T; |
|
||||
|
|
||||
T d = *first; |
|
||||
++first; |
|
||||
while (d != T(1) && first != last) |
|
||||
{ |
|
||||
d = gcd(d, *first); |
|
||||
++first; |
|
||||
} |
|
||||
return std::make_pair(d, first); |
|
||||
} |
|
||||
template <typename I> |
|
||||
std::pair<typename std::iterator_traits<I>::value_type, I> |
|
||||
lcm_range(I first, I last) BOOST_GCD_NOEXCEPT(I) |
|
||||
{ |
|
||||
BOOST_ASSERT(first != last); |
|
||||
typedef typename std::iterator_traits<I>::value_type T; |
|
||||
|
|
||||
T d = *first; |
|
||||
++first; |
|
||||
while (d != T(0) && first != last) |
|
||||
{ |
|
||||
d = lcm(d, *first); |
|
||||
++first; |
|
||||
} |
|
||||
return std::make_pair(d, first); |
|
||||
} |
|
||||
|
|
||||
template < typename IntegerType > |
|
||||
class gcd_evaluator |
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
|
||||
: public std::binary_function<IntegerType, IntegerType, IntegerType> |
|
||||
#endif
|
|
||||
{ |
|
||||
public: |
|
||||
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
|
||||
typedef IntegerType first_argument_type; |
|
||||
typedef IntegerType second_argument_type; |
|
||||
typedef IntegerType result_type; |
|
||||
#endif
|
|
||||
IntegerType operator()(IntegerType const &a, IntegerType const &b) const |
|
||||
{ |
|
||||
return boost::integer::gcd(a, b); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template < typename IntegerType > |
|
||||
class lcm_evaluator |
|
||||
#ifdef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
|
||||
: public std::binary_function<IntegerType, IntegerType, IntegerType> |
|
||||
#endif
|
|
||||
{ |
|
||||
public: |
|
||||
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
|
|
||||
typedef IntegerType first_argument_type; |
|
||||
typedef IntegerType second_argument_type; |
|
||||
typedef IntegerType result_type; |
|
||||
#endif
|
|
||||
IntegerType operator()(IntegerType const &a, IntegerType const &b)const |
|
||||
{ |
|
||||
return boost::integer::lcm(a, b); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} // namespace integer
|
|
||||
} // namespace boost
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
#pragma warning(pop)
|
|
||||
#endif
|
|
||||
|
|
||||
#endif // BOOST_INTEGER_COMMON_FACTOR_RT_HPP
|
|
@ -1,307 +0,0 @@ |
|||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_ALLOCATOR_HPP
|
|
||||
#define BOOST_INTERPROCESS_ALLOCATOR_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
|
||||
|
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
|
||||
#include <boost/interprocess/containers/allocation_type.hpp>
|
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
|
||||
#include <boost/interprocess/allocators/detail/allocator_common.hpp>
|
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
|
||||
#include <boost/interprocess/containers/version_type.hpp>
|
|
||||
#include <boost/interprocess/exceptions.hpp>
|
|
||||
#include <boost/assert.hpp>
|
|
||||
#include <boost/utility/addressof.hpp>
|
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
|
|
||||
#include <cstddef>
|
|
||||
#include <stdexcept>
|
|
||||
|
|
||||
//!\file
|
|
||||
//!Describes an allocator that allocates portions of fixed size
|
|
||||
//!memory buffer (shared memory, mapped file...)
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
|
|
||||
//!An STL compatible allocator that uses a segment manager as
|
|
||||
//!memory source. The internal pointer type will of the same type (raw, smart) as
|
|
||||
//!"typename SegmentManager::void_pointer" type. This allows
|
|
||||
//!placing the allocator in shared memory, memory mapped-files, etc...
|
|
||||
template<class T, class SegmentManager> |
|
||||
class allocator |
|
||||
{ |
|
||||
public: |
|
||||
//Segment manager
|
|
||||
typedef SegmentManager segment_manager; |
|
||||
typedef typename SegmentManager::void_pointer void_pointer; |
|
||||
|
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
private: |
|
||||
|
|
||||
//Self type
|
|
||||
typedef allocator<T, SegmentManager> self_t; |
|
||||
|
|
||||
//Pointer to void
|
|
||||
typedef typename segment_manager::void_pointer aux_pointer_t; |
|
||||
|
|
||||
//Typedef to const void pointer
|
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<aux_pointer_t>::template |
|
||||
rebind_pointer<const void>::type cvoid_ptr; |
|
||||
|
|
||||
//Pointer to the allocator
|
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<cvoid_ptr>::template |
|
||||
rebind_pointer<segment_manager>::type alloc_ptr_t; |
|
||||
|
|
||||
//Not assignable from related allocator
|
|
||||
template<class T2, class SegmentManager2> |
|
||||
allocator& operator=(const allocator<T2, SegmentManager2>&); |
|
||||
|
|
||||
//Not assignable from other allocator
|
|
||||
allocator& operator=(const allocator&); |
|
||||
|
|
||||
//Pointer to the allocator
|
|
||||
alloc_ptr_t mp_mngr; |
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
|
||||
|
|
||||
public: |
|
||||
typedef T value_type; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<cvoid_ptr>::template |
|
||||
rebind_pointer<T>::type pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<pointer>::template |
|
||||
rebind_pointer<const T>::type const_pointer; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<value_type>::type reference; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<const value_type>::type const_reference; |
|
||||
typedef typename segment_manager::size_type size_type; |
|
||||
typedef typename segment_manager::difference_type difference_type; |
|
||||
|
|
||||
typedef boost::interprocess::version_type<allocator, 2> version; |
|
||||
|
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
//Experimental. Don't use.
|
|
||||
typedef boost::container::dtl::transform_multiallocation_chain |
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain; |
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
|
||||
|
|
||||
//!Obtains an allocator that allocates
|
|
||||
//!objects of type T2
|
|
||||
template<class T2> |
|
||||
struct rebind |
|
||||
{ |
|
||||
typedef allocator<T2, SegmentManager> other; |
|
||||
}; |
|
||||
|
|
||||
//!Returns the segment manager.
|
|
||||
//!Never throws
|
|
||||
segment_manager* get_segment_manager()const |
|
||||
{ return ipcdetail::to_raw_pointer(mp_mngr); } |
|
||||
|
|
||||
//!Constructor from the segment manager.
|
|
||||
//!Never throws
|
|
||||
allocator(segment_manager *segment_mngr) |
|
||||
: mp_mngr(segment_mngr) { } |
|
||||
|
|
||||
//!Constructor from other allocator.
|
|
||||
//!Never throws
|
|
||||
allocator(const allocator &other) |
|
||||
: mp_mngr(other.get_segment_manager()){ } |
|
||||
|
|
||||
//!Constructor from related allocator.
|
|
||||
//!Never throws
|
|
||||
template<class T2> |
|
||||
allocator(const allocator<T2, SegmentManager> &other) |
|
||||
: mp_mngr(other.get_segment_manager()){} |
|
||||
|
|
||||
//!Allocates memory for an array of count elements.
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate(size_type count, cvoid_ptr hint = 0) |
|
||||
{ |
|
||||
(void)hint; |
|
||||
if(size_overflows<sizeof(T)>(count)){ |
|
||||
throw bad_alloc(); |
|
||||
} |
|
||||
return pointer(static_cast<value_type*>(mp_mngr->allocate(count*sizeof(T)))); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates memory previously allocated.
|
|
||||
//!Never throws
|
|
||||
void deallocate(const pointer &ptr, size_type) |
|
||||
{ mp_mngr->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); } |
|
||||
|
|
||||
//!Returns the number of elements that could be allocated.
|
|
||||
//!Never throws
|
|
||||
size_type max_size() const |
|
||||
{ return mp_mngr->get_size()/sizeof(T); } |
|
||||
|
|
||||
//!Swap segment manager. Does not throw. If each allocator is placed in
|
|
||||
//!different memory segments, the result is undefined.
|
|
||||
friend void swap(self_t &alloc1, self_t &alloc2) |
|
||||
{ boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); } |
|
||||
|
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
|
||||
//!pointed by p can hold. This size only works for memory allocated with
|
|
||||
//!allocate, allocation_command and allocate_many.
|
|
||||
size_type size(const pointer &p) const |
|
||||
{ |
|
||||
return (size_type)mp_mngr->size(ipcdetail::to_raw_pointer(p))/sizeof(T); |
|
||||
} |
|
||||
|
|
||||
pointer allocation_command(boost::interprocess::allocation_type command, |
|
||||
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) |
|
||||
{ |
|
||||
value_type *reuse_raw = ipcdetail::to_raw_pointer(reuse); |
|
||||
pointer const p = mp_mngr->allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse_raw); |
|
||||
reuse = reuse_raw; |
|
||||
return p; |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
|
||||
//!with deallocate(...)
|
|
||||
void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain) |
|
||||
{ |
|
||||
if(size_overflows<sizeof(T)>(elem_size)){ |
|
||||
throw bad_alloc(); |
|
||||
} |
|
||||
mp_mngr->allocate_many(elem_size*sizeof(T), num_elements, chain); |
|
||||
} |
|
||||
|
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
|
||||
//!contiguous block
|
|
||||
//!of memory. The elements must be deallocated
|
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) |
|
||||
{ |
|
||||
mp_mngr->allocate_many(elem_sizes, n_elements, sizeof(T), chain); |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
|
||||
//!with deallocate(...)
|
|
||||
void deallocate_many(multiallocation_chain &chain) |
|
||||
{ mp_mngr->deallocate_many(chain); } |
|
||||
|
|
||||
//!Allocates just one object. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate_one() |
|
||||
{ return this->allocate(1); } |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void allocate_individual(size_type num_elements, multiallocation_chain &chain) |
|
||||
{ this->allocate_many(1, num_elements, chain); } |
|
||||
|
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
|
||||
//!with other functions different from allocate_one(). Never throws
|
|
||||
void deallocate_one(const pointer &p) |
|
||||
{ return this->deallocate(p, 1); } |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void deallocate_individual(multiallocation_chain &chain) |
|
||||
{ this->deallocate_many(chain); } |
|
||||
|
|
||||
//!Returns address of mutable object.
|
|
||||
//!Never throws
|
|
||||
pointer address(reference value) const |
|
||||
{ return pointer(boost::addressof(value)); } |
|
||||
|
|
||||
//!Returns address of non mutable object.
|
|
||||
//!Never throws
|
|
||||
const_pointer address(const_reference value) const |
|
||||
{ return const_pointer(boost::addressof(value)); } |
|
||||
|
|
||||
//!Constructs an object
|
|
||||
//!Throws if T's constructor throws
|
|
||||
//!For backwards compatibility with libraries using C++03 allocators
|
|
||||
template<class P> |
|
||||
void construct(const pointer &ptr, BOOST_FWD_REF(P) p) |
|
||||
{ ::new((void*)ipcdetail::to_raw_pointer(ptr), boost_container_new_t()) value_type(::boost::forward<P>(p)); } |
|
||||
|
|
||||
//!Destroys object. Throws if object's
|
|
||||
//!destructor throws
|
|
||||
void destroy(const pointer &ptr) |
|
||||
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
//!Equality test for same type
|
|
||||
//!of allocator
|
|
||||
template<class T, class SegmentManager> inline |
|
||||
bool operator==(const allocator<T , SegmentManager> &alloc1, |
|
||||
const allocator<T, SegmentManager> &alloc2) |
|
||||
{ return alloc1.get_segment_manager() == alloc2.get_segment_manager(); } |
|
||||
|
|
||||
//!Inequality test for same type
|
|
||||
//!of allocator
|
|
||||
template<class T, class SegmentManager> inline |
|
||||
bool operator!=(const allocator<T, SegmentManager> &alloc1, |
|
||||
const allocator<T, SegmentManager> &alloc2) |
|
||||
{ return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } |
|
||||
|
|
||||
} //namespace interprocess {
|
|
||||
|
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
|
|
||||
template<class T> |
|
||||
struct has_trivial_destructor; |
|
||||
|
|
||||
template<class T, class SegmentManager> |
|
||||
struct has_trivial_destructor |
|
||||
<boost::interprocess::allocator <T, SegmentManager> > |
|
||||
{ |
|
||||
static const bool value = true; |
|
||||
}; |
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
|
||||
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_INTERPROCESS_ALLOCATOR_HPP
|
|
||||
|
|
@ -1,857 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
|
|
||||
#define BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
|
||||
|
|
||||
#include <boost/interprocess/interprocess_fwd.hpp>
|
|
||||
#include <boost/interprocess/detail/utilities.hpp> //to_raw_pointer
|
|
||||
#include <boost/utility/addressof.hpp> //boost::addressof
|
|
||||
#include <boost/assert.hpp> //BOOST_ASSERT
|
|
||||
#include <boost/interprocess/exceptions.hpp> //bad_alloc
|
|
||||
#include <boost/interprocess/sync/scoped_lock.hpp> //scoped_lock
|
|
||||
#include <boost/interprocess/containers/allocation_type.hpp> //boost::interprocess::allocation_type
|
|
||||
#include <boost/container/detail/multiallocation_chain.hpp>
|
|
||||
#include <boost/interprocess/mem_algo/detail/mem_algo_common.hpp>
|
|
||||
#include <boost/interprocess/detail/segment_manager_helper.hpp>
|
|
||||
#include <boost/move/utility_core.hpp>
|
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
|
||||
#include <boost/interprocess/detail/utilities.hpp>
|
|
||||
#include <boost/container/detail/placement_new.hpp>
|
|
||||
#include <boost/move/adl_move_swap.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
template <class T> |
|
||||
struct sizeof_value |
|
||||
{ |
|
||||
static const std::size_t value = sizeof(T); |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct sizeof_value<void> |
|
||||
{ |
|
||||
static const std::size_t value = sizeof(void*); |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct sizeof_value<const void> |
|
||||
{ |
|
||||
static const std::size_t value = sizeof(void*); |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct sizeof_value<volatile void> |
|
||||
{ |
|
||||
static const std::size_t value = sizeof(void*); |
|
||||
}; |
|
||||
|
|
||||
template <> |
|
||||
struct sizeof_value<const volatile void> |
|
||||
{ |
|
||||
static const std::size_t value = sizeof(void*); |
|
||||
}; |
|
||||
|
|
||||
namespace ipcdetail { |
|
||||
|
|
||||
//!Object function that creates the node allocator if it is not created and
|
|
||||
//!increments reference count if it is already created
|
|
||||
template<class NodePool> |
|
||||
struct get_or_create_node_pool_func |
|
||||
{ |
|
||||
|
|
||||
//!This connects or constructs the unique instance of node_pool_t
|
|
||||
//!Can throw boost::interprocess::bad_alloc
|
|
||||
void operator()() |
|
||||
{ |
|
||||
//Find or create the node_pool_t
|
|
||||
mp_node_pool = mp_segment_manager->template find_or_construct |
|
||||
<NodePool>(boost::interprocess::unique_instance)(mp_segment_manager); |
|
||||
//If valid, increment link count
|
|
||||
if(mp_node_pool != 0) |
|
||||
mp_node_pool->inc_ref_count(); |
|
||||
} |
|
||||
|
|
||||
//!Constructor. Initializes function
|
|
||||
//!object parameters
|
|
||||
get_or_create_node_pool_func(typename NodePool::segment_manager *mngr) |
|
||||
: mp_segment_manager(mngr){} |
|
||||
|
|
||||
NodePool *mp_node_pool; |
|
||||
typename NodePool::segment_manager *mp_segment_manager; |
|
||||
}; |
|
||||
|
|
||||
template<class NodePool> |
|
||||
inline NodePool *get_or_create_node_pool(typename NodePool::segment_manager *mgnr) |
|
||||
{ |
|
||||
ipcdetail::get_or_create_node_pool_func<NodePool> func(mgnr); |
|
||||
mgnr->atomic_func(func); |
|
||||
return func.mp_node_pool; |
|
||||
} |
|
||||
|
|
||||
//!Object function that decrements the reference count. If the count
|
|
||||
//!reaches to zero destroys the node allocator from memory.
|
|
||||
//!Never throws
|
|
||||
template<class NodePool> |
|
||||
struct destroy_if_last_link_func |
|
||||
{ |
|
||||
//!Decrements reference count and destroys the object if there is no
|
|
||||
//!more attached allocators. Never throws
|
|
||||
void operator()() |
|
||||
{ |
|
||||
//If not the last link return
|
|
||||
if(mp_node_pool->dec_ref_count() != 0) return; |
|
||||
|
|
||||
//Last link, let's destroy the segment_manager
|
|
||||
mp_node_pool->get_segment_manager()->template destroy<NodePool>(boost::interprocess::unique_instance); |
|
||||
} |
|
||||
|
|
||||
//!Constructor. Initializes function
|
|
||||
//!object parameters
|
|
||||
destroy_if_last_link_func(NodePool *pool) |
|
||||
: mp_node_pool(pool) |
|
||||
{} |
|
||||
|
|
||||
NodePool *mp_node_pool; |
|
||||
}; |
|
||||
|
|
||||
//!Destruction function, initializes and executes destruction function
|
|
||||
//!object. Never throws
|
|
||||
template<class NodePool> |
|
||||
inline void destroy_node_pool_if_last_link(NodePool *pool) |
|
||||
{ |
|
||||
//Get segment manager
|
|
||||
typename NodePool::segment_manager *mngr = pool->get_segment_manager(); |
|
||||
//Execute destruction functor atomically
|
|
||||
destroy_if_last_link_func<NodePool>func(pool); |
|
||||
mngr->atomic_func(func); |
|
||||
} |
|
||||
|
|
||||
template<class NodePool> |
|
||||
class cache_impl |
|
||||
{ |
|
||||
typedef typename NodePool::segment_manager:: |
|
||||
void_pointer void_pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<NodePool>::type node_pool_ptr; |
|
||||
typedef typename NodePool::multiallocation_chain multiallocation_chain; |
|
||||
typedef typename NodePool::segment_manager::size_type size_type; |
|
||||
node_pool_ptr mp_node_pool; |
|
||||
multiallocation_chain m_cached_nodes; |
|
||||
size_type m_max_cached_nodes; |
|
||||
|
|
||||
public: |
|
||||
typedef typename NodePool::segment_manager segment_manager; |
|
||||
|
|
||||
cache_impl(segment_manager *segment_mngr, size_type max_cached_nodes) |
|
||||
: mp_node_pool(get_or_create_node_pool<NodePool>(segment_mngr)) |
|
||||
, m_max_cached_nodes(max_cached_nodes) |
|
||||
{} |
|
||||
|
|
||||
cache_impl(const cache_impl &other) |
|
||||
: mp_node_pool(other.get_node_pool()) |
|
||||
, m_max_cached_nodes(other.get_max_cached_nodes()) |
|
||||
{ |
|
||||
mp_node_pool->inc_ref_count(); |
|
||||
} |
|
||||
|
|
||||
~cache_impl() |
|
||||
{ |
|
||||
this->deallocate_all_cached_nodes(); |
|
||||
ipcdetail::destroy_node_pool_if_last_link(ipcdetail::to_raw_pointer(mp_node_pool)); |
|
||||
} |
|
||||
|
|
||||
NodePool *get_node_pool() const |
|
||||
{ return ipcdetail::to_raw_pointer(mp_node_pool); } |
|
||||
|
|
||||
segment_manager *get_segment_manager() const |
|
||||
{ return mp_node_pool->get_segment_manager(); } |
|
||||
|
|
||||
size_type get_max_cached_nodes() const |
|
||||
{ return m_max_cached_nodes; } |
|
||||
|
|
||||
void *cached_allocation() |
|
||||
{ |
|
||||
//If don't have any cached node, we have to get a new list of free nodes from the pool
|
|
||||
if(m_cached_nodes.empty()){ |
|
||||
mp_node_pool->allocate_nodes(m_max_cached_nodes/2, m_cached_nodes); |
|
||||
} |
|
||||
void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.pop_front()); |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
void cached_allocation(size_type n, multiallocation_chain &chain) |
|
||||
{ |
|
||||
size_type count = n, allocated(0); |
|
||||
BOOST_TRY{ |
|
||||
//If don't have any cached node, we have to get a new list of free nodes from the pool
|
|
||||
while(!m_cached_nodes.empty() && count--){ |
|
||||
void *ret = ipcdetail::to_raw_pointer(m_cached_nodes.pop_front()); |
|
||||
chain.push_back(ret); |
|
||||
++allocated; |
|
||||
} |
|
||||
|
|
||||
if(allocated != n){ |
|
||||
mp_node_pool->allocate_nodes(n - allocated, chain); |
|
||||
} |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
this->cached_deallocation(chain); |
|
||||
BOOST_RETHROW |
|
||||
} BOOST_CATCH_END |
|
||||
} |
|
||||
|
|
||||
void cached_deallocation(void *ptr) |
|
||||
{ |
|
||||
//Check if cache is full
|
|
||||
if(m_cached_nodes.size() >= m_max_cached_nodes){ |
|
||||
//This only occurs if this allocator deallocate memory allocated
|
|
||||
//with other equal allocator. Since the cache is full, and more
|
|
||||
//deallocations are probably coming, we'll make some room in cache
|
|
||||
//in a single, efficient multi node deallocation.
|
|
||||
this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2); |
|
||||
} |
|
||||
m_cached_nodes.push_front(ptr); |
|
||||
} |
|
||||
|
|
||||
void cached_deallocation(multiallocation_chain &chain) |
|
||||
{ |
|
||||
m_cached_nodes.splice_after(m_cached_nodes.before_begin(), chain); |
|
||||
|
|
||||
//Check if cache is full
|
|
||||
if(m_cached_nodes.size() >= m_max_cached_nodes){ |
|
||||
//This only occurs if this allocator deallocate memory allocated
|
|
||||
//with other equal allocator. Since the cache is full, and more
|
|
||||
//deallocations are probably coming, we'll make some room in cache
|
|
||||
//in a single, efficient multi node deallocation.
|
|
||||
this->priv_deallocate_n_nodes(m_cached_nodes.size() - m_max_cached_nodes/2); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
|
||||
void set_max_cached_nodes(size_type newmax) |
|
||||
{ |
|
||||
m_max_cached_nodes = newmax; |
|
||||
this->priv_deallocate_remaining_nodes(); |
|
||||
} |
|
||||
|
|
||||
//!Frees all cached nodes.
|
|
||||
//!Never throws
|
|
||||
void deallocate_all_cached_nodes() |
|
||||
{ |
|
||||
if(m_cached_nodes.empty()) return; |
|
||||
mp_node_pool->deallocate_nodes(m_cached_nodes); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
//!Frees all cached nodes at once.
|
|
||||
//!Never throws
|
|
||||
void priv_deallocate_remaining_nodes() |
|
||||
{ |
|
||||
if(m_cached_nodes.size() > m_max_cached_nodes){ |
|
||||
priv_deallocate_n_nodes(m_cached_nodes.size()-m_max_cached_nodes); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//!Frees n cached nodes at once. Never throws
|
|
||||
void priv_deallocate_n_nodes(size_type n) |
|
||||
{ |
|
||||
//This only occurs if this allocator deallocate memory allocated
|
|
||||
//with other equal allocator. Since the cache is full, and more
|
|
||||
//deallocations are probably coming, we'll make some room in cache
|
|
||||
//in a single, efficient multi node deallocation.
|
|
||||
size_type count(n); |
|
||||
typename multiallocation_chain::iterator it(m_cached_nodes.before_begin()); |
|
||||
while(count--){ |
|
||||
++it; |
|
||||
} |
|
||||
multiallocation_chain chain; |
|
||||
chain.splice_after(chain.before_begin(), m_cached_nodes, m_cached_nodes.before_begin(), it, n); |
|
||||
//Deallocate all new linked list at once
|
|
||||
mp_node_pool->deallocate_nodes(chain); |
|
||||
} |
|
||||
|
|
||||
public: |
|
||||
void swap(cache_impl &other) |
|
||||
{ |
|
||||
::boost::adl_move_swap(mp_node_pool, other.mp_node_pool); |
|
||||
::boost::adl_move_swap(m_cached_nodes, other.m_cached_nodes); |
|
||||
::boost::adl_move_swap(m_max_cached_nodes, other.m_max_cached_nodes); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<class Derived, class T, class SegmentManager> |
|
||||
class array_allocation_impl |
|
||||
{ |
|
||||
const Derived *derived() const |
|
||||
{ return static_cast<const Derived*>(this); } |
|
||||
Derived *derived() |
|
||||
{ return static_cast<Derived*>(this); } |
|
||||
|
|
||||
typedef typename SegmentManager::void_pointer void_pointer; |
|
||||
|
|
||||
public: |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<T>::type pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<const T>::type const_pointer; |
|
||||
typedef T value_type; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<value_type>::type reference; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<const value_type>::type const_reference; |
|
||||
typedef typename SegmentManager::size_type size_type; |
|
||||
typedef typename SegmentManager::difference_type difference_type; |
|
||||
typedef boost::container::dtl::transform_multiallocation_chain |
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain; |
|
||||
|
|
||||
|
|
||||
public: |
|
||||
//!Returns maximum the number of objects the previously allocated memory
|
|
||||
//!pointed by p can hold. This size only works for memory allocated with
|
|
||||
//!allocate, allocation_command and allocate_many.
|
|
||||
size_type size(const pointer &p) const |
|
||||
{ |
|
||||
return (size_type)this->derived()->get_segment_manager()->size(ipcdetail::to_raw_pointer(p))/sizeof(T); |
|
||||
} |
|
||||
|
|
||||
pointer allocation_command(boost::interprocess::allocation_type command, |
|
||||
size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) |
|
||||
{ |
|
||||
value_type *reuse_raw = ipcdetail::to_raw_pointer(reuse); |
|
||||
pointer const p = this->derived()->get_segment_manager()->allocation_command |
|
||||
(command, limit_size, prefer_in_recvd_out_size, reuse_raw); |
|
||||
reuse = reuse_raw; |
|
||||
return p; |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
|
||||
//!with deallocate(...)
|
|
||||
void allocate_many(size_type elem_size, size_type num_elements, multiallocation_chain &chain) |
|
||||
{ |
|
||||
if(size_overflows<sizeof(T)>(elem_size)){ |
|
||||
throw bad_alloc(); |
|
||||
} |
|
||||
this->derived()->get_segment_manager()->allocate_many(elem_size*sizeof(T), num_elements, chain); |
|
||||
} |
|
||||
|
|
||||
//!Allocates n_elements elements, each one of size elem_sizes[i]in a
|
|
||||
//!contiguous block
|
|
||||
//!of memory. The elements must be deallocated
|
|
||||
void allocate_many(const size_type *elem_sizes, size_type n_elements, multiallocation_chain &chain) |
|
||||
{ |
|
||||
this->derived()->get_segment_manager()->allocate_many(elem_sizes, n_elements, sizeof(T), chain); |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size elem_size in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. The elements must be deallocated
|
|
||||
//!with deallocate(...)
|
|
||||
void deallocate_many(multiallocation_chain &chain) |
|
||||
{ this->derived()->get_segment_manager()->deallocate_many(chain); } |
|
||||
|
|
||||
//!Returns the number of elements that could be
|
|
||||
//!allocated. Never throws
|
|
||||
size_type max_size() const |
|
||||
{ return this->derived()->get_segment_manager()->get_size()/sizeof(T); } |
|
||||
|
|
||||
//!Returns address of mutable object.
|
|
||||
//!Never throws
|
|
||||
pointer address(reference value) const |
|
||||
{ return pointer(boost::addressof(value)); } |
|
||||
|
|
||||
//!Returns address of non mutable object.
|
|
||||
//!Never throws
|
|
||||
const_pointer address(const_reference value) const |
|
||||
{ return const_pointer(boost::addressof(value)); } |
|
||||
|
|
||||
//!Constructs an object
|
|
||||
//!Throws if T's constructor throws
|
|
||||
//!For backwards compatibility with libraries using C++03 allocators
|
|
||||
template<class P> |
|
||||
void construct(const pointer &ptr, BOOST_FWD_REF(P) p) |
|
||||
{ ::new((void*)ipcdetail::to_raw_pointer(ptr), boost_container_new_t()) value_type(::boost::forward<P>(p)); } |
|
||||
|
|
||||
//!Destroys object. Throws if object's
|
|
||||
//!destructor throws
|
|
||||
void destroy(const pointer &ptr) |
|
||||
{ BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
template<class Derived, unsigned int Version, class T, class SegmentManager> |
|
||||
class node_pool_allocation_impl |
|
||||
: public array_allocation_impl |
|
||||
< Derived |
|
||||
, T |
|
||||
, SegmentManager> |
|
||||
{ |
|
||||
const Derived *derived() const |
|
||||
{ return static_cast<const Derived*>(this); } |
|
||||
Derived *derived() |
|
||||
{ return static_cast<Derived*>(this); } |
|
||||
|
|
||||
typedef typename SegmentManager::void_pointer void_pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<const void>::type cvoid_pointer; |
|
||||
|
|
||||
public: |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<T>::type pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<const T>::type const_pointer; |
|
||||
typedef T value_type; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<value_type>::type reference; |
|
||||
typedef typename ipcdetail::add_reference |
|
||||
<const value_type>::type const_reference; |
|
||||
typedef typename SegmentManager::size_type size_type; |
|
||||
typedef typename SegmentManager::difference_type difference_type; |
|
||||
typedef boost::container::dtl::transform_multiallocation_chain |
|
||||
<typename SegmentManager::multiallocation_chain, T>multiallocation_chain; |
|
||||
|
|
||||
|
|
||||
template <int Dummy> |
|
||||
struct node_pool |
|
||||
{ |
|
||||
typedef typename Derived::template node_pool<0>::type type; |
|
||||
static type *get(void *p) |
|
||||
{ return static_cast<type*>(p); } |
|
||||
}; |
|
||||
|
|
||||
public: |
|
||||
//!Allocate memory for an array of count elements.
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate(size_type count, cvoid_pointer hint = 0) |
|
||||
{ |
|
||||
(void)hint; |
|
||||
typedef typename node_pool<0>::type node_pool_t; |
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); |
|
||||
if(size_overflows<sizeof(T)>(count)){ |
|
||||
throw bad_alloc(); |
|
||||
} |
|
||||
else if(Version == 1 && count == 1){ |
|
||||
return pointer(static_cast<value_type*> |
|
||||
(pool->allocate_node())); |
|
||||
} |
|
||||
else{ |
|
||||
return pointer(static_cast<value_type*> |
|
||||
(pool->get_segment_manager()->allocate(count*sizeof(T)))); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//!Deallocate allocated memory. Never throws
|
|
||||
void deallocate(const pointer &ptr, size_type count) |
|
||||
{ |
|
||||
(void)count; |
|
||||
typedef typename node_pool<0>::type node_pool_t; |
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); |
|
||||
if(Version == 1 && count == 1) |
|
||||
pool->deallocate_node(ipcdetail::to_raw_pointer(ptr)); |
|
||||
else |
|
||||
pool->get_segment_manager()->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); |
|
||||
} |
|
||||
|
|
||||
//!Allocates just one object. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate_one() |
|
||||
{ |
|
||||
typedef typename node_pool<0>::type node_pool_t; |
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); |
|
||||
return pointer(static_cast<value_type*>(pool->allocate_node())); |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void allocate_individual(size_type num_elements, multiallocation_chain &chain) |
|
||||
{ |
|
||||
typedef typename node_pool<0>::type node_pool_t; |
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); |
|
||||
pool->allocate_nodes(num_elements, chain); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
|
||||
//!with other functions different from allocate_one(). Never throws
|
|
||||
void deallocate_one(const pointer &p) |
|
||||
{ |
|
||||
typedef typename node_pool<0>::type node_pool_t; |
|
||||
node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool()); |
|
||||
pool->deallocate_node(ipcdetail::to_raw_pointer(p)); |
|
||||
} |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void deallocate_individual(multiallocation_chain &chain) |
|
||||
{ |
|
||||
node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes |
|
||||
(chain); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates all free blocks of the pool
|
|
||||
void deallocate_free_blocks() |
|
||||
{ node_pool<0>::get(this->derived()->get_node_pool())->deallocate_free_blocks(); } |
|
||||
|
|
||||
//!Deprecated, use deallocate_free_blocks.
|
|
||||
//!Deallocates all free chunks of the pool.
|
|
||||
void deallocate_free_chunks() |
|
||||
{ node_pool<0>::get(this->derived()->get_node_pool())->deallocate_free_blocks(); } |
|
||||
}; |
|
||||
|
|
||||
template<class T, class NodePool, unsigned int Version> |
|
||||
class cached_allocator_impl |
|
||||
: public array_allocation_impl |
|
||||
<cached_allocator_impl<T, NodePool, Version>, T, typename NodePool::segment_manager> |
|
||||
{ |
|
||||
cached_allocator_impl & operator=(const cached_allocator_impl& other); |
|
||||
typedef array_allocation_impl |
|
||||
< cached_allocator_impl |
|
||||
<T, NodePool, Version> |
|
||||
, T |
|
||||
, typename NodePool::segment_manager> base_t; |
|
||||
|
|
||||
public: |
|
||||
typedef NodePool node_pool_t; |
|
||||
typedef typename NodePool::segment_manager segment_manager; |
|
||||
typedef typename segment_manager::void_pointer void_pointer; |
|
||||
typedef typename boost::intrusive:: |
|
||||
pointer_traits<void_pointer>::template |
|
||||
rebind_pointer<const void>::type cvoid_pointer; |
|
||||
typedef typename base_t::pointer pointer; |
|
||||
typedef typename base_t::size_type size_type; |
|
||||
typedef typename base_t::multiallocation_chain multiallocation_chain; |
|
||||
typedef typename base_t::value_type value_type; |
|
||||
|
|
||||
public: |
|
||||
static const std::size_t DEFAULT_MAX_CACHED_NODES = 64; |
|
||||
|
|
||||
cached_allocator_impl(segment_manager *segment_mngr, size_type max_cached_nodes) |
|
||||
: m_cache(segment_mngr, max_cached_nodes) |
|
||||
{} |
|
||||
|
|
||||
cached_allocator_impl(const cached_allocator_impl &other) |
|
||||
: m_cache(other.m_cache) |
|
||||
{} |
|
||||
|
|
||||
//!Copy constructor from related cached_adaptive_pool_base. If not present, constructs
|
|
||||
//!a node pool. Increments the reference count of the associated node pool.
|
|
||||
//!Can throw boost::interprocess::bad_alloc
|
|
||||
template<class T2, class NodePool2> |
|
||||
cached_allocator_impl |
|
||||
(const cached_allocator_impl |
|
||||
<T2, NodePool2, Version> &other) |
|
||||
: m_cache(other.get_segment_manager(), other.get_max_cached_nodes()) |
|
||||
{} |
|
||||
|
|
||||
//!Returns a pointer to the node pool.
|
|
||||
//!Never throws
|
|
||||
node_pool_t* get_node_pool() const |
|
||||
{ return m_cache.get_node_pool(); } |
|
||||
|
|
||||
//!Returns the segment manager.
|
|
||||
//!Never throws
|
|
||||
segment_manager* get_segment_manager()const |
|
||||
{ return m_cache.get_segment_manager(); } |
|
||||
|
|
||||
//!Sets the new max cached nodes value. This can provoke deallocations
|
|
||||
//!if "newmax" is less than current cached nodes. Never throws
|
|
||||
void set_max_cached_nodes(size_type newmax) |
|
||||
{ m_cache.set_max_cached_nodes(newmax); } |
|
||||
|
|
||||
//!Returns the max cached nodes parameter.
|
|
||||
//!Never throws
|
|
||||
size_type get_max_cached_nodes() const |
|
||||
{ return m_cache.get_max_cached_nodes(); } |
|
||||
|
|
||||
//!Allocate memory for an array of count elements.
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate(size_type count, cvoid_pointer hint = 0) |
|
||||
{ |
|
||||
(void)hint; |
|
||||
void * ret; |
|
||||
if(size_overflows<sizeof(T)>(count)){ |
|
||||
throw bad_alloc(); |
|
||||
} |
|
||||
else if(Version == 1 && count == 1){ |
|
||||
ret = m_cache.cached_allocation(); |
|
||||
} |
|
||||
else{ |
|
||||
ret = this->get_segment_manager()->allocate(count*sizeof(T)); |
|
||||
} |
|
||||
return pointer(static_cast<T*>(ret)); |
|
||||
} |
|
||||
|
|
||||
//!Deallocate allocated memory. Never throws
|
|
||||
void deallocate(const pointer &ptr, size_type count) |
|
||||
{ |
|
||||
(void)count; |
|
||||
if(Version == 1 && count == 1){ |
|
||||
m_cache.cached_deallocation(ipcdetail::to_raw_pointer(ptr)); |
|
||||
} |
|
||||
else{ |
|
||||
this->get_segment_manager()->deallocate((void*)ipcdetail::to_raw_pointer(ptr)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//!Allocates just one object. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
//!Throws boost::interprocess::bad_alloc if there is no enough memory
|
|
||||
pointer allocate_one() |
|
||||
{ return pointer(static_cast<value_type*>(this->m_cache.cached_allocation())); } |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void allocate_individual(size_type num_elements, multiallocation_chain &chain) |
|
||||
{ this->m_cache.cached_allocation(num_elements, chain); } |
|
||||
|
|
||||
//!Deallocates memory previously allocated with allocate_one().
|
|
||||
//!You should never use deallocate_one to deallocate memory allocated
|
|
||||
//!with other functions different from allocate_one(). Never throws
|
|
||||
void deallocate_one(const pointer &p) |
|
||||
{ this->m_cache.cached_deallocation(ipcdetail::to_raw_pointer(p)); } |
|
||||
|
|
||||
//!Allocates many elements of size == 1 in a contiguous block
|
|
||||
//!of memory. The minimum number to be allocated is min_elements,
|
|
||||
//!the preferred and maximum number is
|
|
||||
//!preferred_elements. The number of actually allocated elements is
|
|
||||
//!will be assigned to received_size. Memory allocated with this function
|
|
||||
//!must be deallocated only with deallocate_one().
|
|
||||
void deallocate_individual(multiallocation_chain &chain) |
|
||||
{ m_cache.cached_deallocation(chain); } |
|
||||
|
|
||||
//!Deallocates all free blocks of the pool
|
|
||||
void deallocate_free_blocks() |
|
||||
{ m_cache.get_node_pool()->deallocate_free_blocks(); } |
|
||||
|
|
||||
//!Swaps allocators. Does not throw. If each allocator is placed in a
|
|
||||
//!different shared memory segments, the result is undefined.
|
|
||||
friend void swap(cached_allocator_impl &alloc1, cached_allocator_impl &alloc2) |
|
||||
{ ::boost::adl_move_swap(alloc1.m_cache, alloc2.m_cache); } |
|
||||
|
|
||||
void deallocate_cache() |
|
||||
{ m_cache.deallocate_all_cached_nodes(); } |
|
||||
|
|
||||
//!Deprecated use deallocate_free_blocks.
|
|
||||
void deallocate_free_chunks() |
|
||||
{ m_cache.get_node_pool()->deallocate_free_blocks(); } |
|
||||
|
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
private: |
|
||||
cache_impl<node_pool_t> m_cache; |
|
||||
#endif //!defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
}; |
|
||||
|
|
||||
//!Equality test for same type of
|
|
||||
//!cached_allocator_impl
|
|
||||
template<class T, class N, unsigned int V> inline |
|
||||
bool operator==(const cached_allocator_impl<T, N, V> &alloc1, |
|
||||
const cached_allocator_impl<T, N, V> &alloc2) |
|
||||
{ return alloc1.get_node_pool() == alloc2.get_node_pool(); } |
|
||||
|
|
||||
//!Inequality test for same type of
|
|
||||
//!cached_allocator_impl
|
|
||||
template<class T, class N, unsigned int V> inline |
|
||||
bool operator!=(const cached_allocator_impl<T, N, V> &alloc1, |
|
||||
const cached_allocator_impl<T, N, V> &alloc2) |
|
||||
{ return alloc1.get_node_pool() != alloc2.get_node_pool(); } |
|
||||
|
|
||||
|
|
||||
//!Pooled shared memory allocator using adaptive pool. Includes
|
|
||||
//!a reference count but the class does not delete itself, this is
|
|
||||
//!responsibility of user classes. Node size (NodeSize) and the number of
|
|
||||
//!nodes allocated per block (NodesPerBlock) are known at compile time
|
|
||||
template<class private_node_allocator_t> |
|
||||
class shared_pool_impl |
|
||||
: public private_node_allocator_t |
|
||||
{ |
|
||||
public: |
|
||||
//!Segment manager typedef
|
|
||||
typedef typename private_node_allocator_t:: |
|
||||
segment_manager segment_manager; |
|
||||
typedef typename private_node_allocator_t:: |
|
||||
multiallocation_chain multiallocation_chain; |
|
||||
typedef typename private_node_allocator_t:: |
|
||||
size_type size_type; |
|
||||
|
|
||||
private: |
|
||||
typedef typename segment_manager::mutex_family::mutex_type mutex_type; |
|
||||
|
|
||||
public: |
|
||||
//!Constructor from a segment manager. Never throws
|
|
||||
shared_pool_impl(segment_manager *segment_mngr) |
|
||||
: private_node_allocator_t(segment_mngr) |
|
||||
{} |
|
||||
|
|
||||
//!Destructor. Deallocates all allocated blocks. Never throws
|
|
||||
~shared_pool_impl() |
|
||||
{} |
|
||||
|
|
||||
//!Allocates array of count elements. Can throw boost::interprocess::bad_alloc
|
|
||||
void *allocate_node() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
return private_node_allocator_t::allocate_node(); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates an array pointed by ptr. Never throws
|
|
||||
void deallocate_node(void *ptr) |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::deallocate_node(ptr); |
|
||||
} |
|
||||
|
|
||||
//!Allocates n nodes.
|
|
||||
//!Can throw boost::interprocess::bad_alloc
|
|
||||
void allocate_nodes(const size_type n, multiallocation_chain &chain) |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::allocate_nodes(n, chain); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates a linked list of nodes ending in null pointer. Never throws
|
|
||||
void deallocate_nodes(multiallocation_chain &nodes, size_type num) |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::deallocate_nodes(nodes, num); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates the nodes pointed by the multiallocation iterator. Never throws
|
|
||||
void deallocate_nodes(multiallocation_chain &chain) |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::deallocate_nodes(chain); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates all the free blocks of memory. Never throws
|
|
||||
void deallocate_free_blocks() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::deallocate_free_blocks(); |
|
||||
} |
|
||||
|
|
||||
//!Deallocates all used memory from the common pool.
|
|
||||
//!Precondition: all nodes allocated from this pool should
|
|
||||
//!already be deallocated. Otherwise, undefined behavior. Never throws
|
|
||||
void purge_blocks() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::purge_blocks(); |
|
||||
} |
|
||||
|
|
||||
//!Increments internal reference count and returns new count. Never throws
|
|
||||
size_type inc_ref_count() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
return ++m_header.m_usecount; |
|
||||
} |
|
||||
|
|
||||
//!Decrements internal reference count and returns new count. Never throws
|
|
||||
size_type dec_ref_count() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
BOOST_ASSERT(m_header.m_usecount > 0); |
|
||||
return --m_header.m_usecount; |
|
||||
} |
|
||||
|
|
||||
//!Deprecated, use deallocate_free_blocks.
|
|
||||
void deallocate_free_chunks() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::deallocate_free_blocks(); |
|
||||
} |
|
||||
|
|
||||
//!Deprecated, use purge_blocks.
|
|
||||
void purge_chunks() |
|
||||
{ |
|
||||
//-----------------------
|
|
||||
boost::interprocess::scoped_lock<mutex_type> guard(m_header); |
|
||||
//-----------------------
|
|
||||
private_node_allocator_t::purge_blocks(); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
//!This struct includes needed data and derives from
|
|
||||
//!the mutex type to allow EBO when using null_mutex
|
|
||||
struct header_t : mutex_type |
|
||||
{ |
|
||||
size_type m_usecount; //Number of attached allocators
|
|
||||
|
|
||||
header_t() |
|
||||
: m_usecount(0) {} |
|
||||
} m_header; |
|
||||
}; |
|
||||
|
|
||||
} //namespace ipcdetail {
|
|
||||
} //namespace interprocess {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_ALLOCATOR_DETAIL_ALLOCATOR_COMMON_HPP
|
|
@ -1,44 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_CONTAINERS_ALLOCATION_TYPE_HPP
|
|
||||
#define BOOST_INTERPROCESS_CONTAINERS_ALLOCATION_TYPE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/allocation_type.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
|
||||
using boost::container::allocation_type; |
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
|
||||
static const allocation_type allocate_new = boost::container::allocate_new; |
|
||||
static const allocation_type expand_fwd = boost::container::expand_fwd; |
|
||||
static const allocation_type expand_bwd = boost::container::expand_bwd; |
|
||||
static const allocation_type shrink_in_place = boost::container::shrink_in_place; |
|
||||
static const allocation_type try_shrink_in_place= boost::container::try_shrink_in_place; |
|
||||
static const allocation_type nothrow_allocation = boost::container::nothrow_allocation; |
|
||||
static const allocation_type zero_memory = boost::container::zero_memory; |
|
||||
|
|
||||
} //namespace interprocess {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_ALLOCATION_TYPE_HPP
|
|
@ -1,37 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
|
|
||||
#define BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/container/detail/version_type.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
using boost::container::dtl::version_type; |
|
||||
using boost::container::dtl::version; |
|
||||
|
|
||||
} //namespace interprocess {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif // #ifndef BOOST_INTERPROCESS_CONTAINERS_VERSION_TYPE_HPP
|
|
||||
|
|
@ -1,85 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_CREATION_TAGS_HPP
|
|
||||
#define BOOST_INTERPROCESS_CREATION_TAGS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be only created
|
|
||||
struct create_only_t {}; |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be only opened
|
|
||||
struct open_only_t {}; |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be only opened for reading
|
|
||||
struct open_read_only_t {}; |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be only opened privately for reading
|
|
||||
struct open_read_private_t {}; |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be only opened for reading
|
|
||||
struct open_copy_on_write_t {}; |
|
||||
|
|
||||
//!Tag to indicate that the resource must
|
|
||||
//!be created. If already created, it must be opened.
|
|
||||
struct open_or_create_t {}; |
|
||||
|
|
||||
//!Value to indicate that the resource must
|
|
||||
//!be only created
|
|
||||
static const create_only_t create_only = create_only_t(); |
|
||||
|
|
||||
//!Value to indicate that the resource must
|
|
||||
//!be only opened
|
|
||||
static const open_only_t open_only = open_only_t(); |
|
||||
|
|
||||
//!Value to indicate that the resource must
|
|
||||
//!be only opened for reading
|
|
||||
static const open_read_only_t open_read_only = open_read_only_t(); |
|
||||
|
|
||||
//!Value to indicate that the resource must
|
|
||||
//!be created. If already created, it must be opened.
|
|
||||
static const open_or_create_t open_or_create = open_or_create_t(); |
|
||||
|
|
||||
//!Value to indicate that the resource must
|
|
||||
//!be only opened for reading
|
|
||||
static const open_copy_on_write_t open_copy_on_write = open_copy_on_write_t(); |
|
||||
|
|
||||
namespace ipcdetail { |
|
||||
|
|
||||
enum create_enum_t |
|
||||
{ DoCreate, DoOpen, DoOpenOrCreate }; |
|
||||
|
|
||||
} //namespace ipcdetail {
|
|
||||
|
|
||||
} //namespace interprocess {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_CREATION_TAGS_HPP
|
|
||||
|
|
@ -1,674 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
|
||||
// (C) Copyright Markus Schoepflin 2007
|
|
||||
// (C) Copyright Bryce Lelbach 2010
|
|
||||
//
|
|
||||
// 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
#include <boost/cstdint.hpp>
|
|
||||
|
|
||||
#if !defined(_AIX)
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_PPC_ASM_LABEL(label) label ":\n\t"
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_PPC_ASM_JUMP(insn, label, offset) insn " " label "\n\t"
|
|
||||
#else
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_PPC_ASM_LABEL(label)
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_PPC_ASM_JUMP(insn, label, offset) insn " $" offset "\n\t"
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically increment an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem); |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem); |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val); |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with": what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp); |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#if defined (BOOST_INTERPROCESS_WINDOWS)
|
|
||||
|
|
||||
#include <boost/interprocess/detail/win32_api.hpp>
|
|
||||
|
|
||||
#if defined( _MSC_VER )
|
|
||||
extern "C" void _ReadWriteBarrier(void); |
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
|
||||
|
|
||||
#define BOOST_INTERPROCESS_READ_WRITE_BARRIER \
|
|
||||
BOOST_INTERPROCESS_DISABLE_DEPRECATED_WARNING \ |
|
||||
_ReadWriteBarrier() \ |
|
||||
BOOST_INTERPROCESS_RESTORE_WARNING |
|
||||
|
|
||||
#elif defined(__GNUC__)
|
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
|
||||
#define BOOST_INTERPROCESS_READ_WRITE_BARRIER __sync_synchronize()
|
|
||||
#else
|
|
||||
#define BOOST_INTERPROCESS_READ_WRITE_BARRIER __asm__ __volatile__("" : : : "memory")
|
|
||||
#endif
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return (boost::uint32_t)winapi::interlocked_decrement(reinterpret_cast<volatile long*>(mem)) + 1; } |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return (boost::uint32_t)winapi::interlocked_increment(reinterpret_cast<volatile long*>(mem))-1; } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ |
|
||||
const boost::uint32_t val = *mem; |
|
||||
BOOST_INTERPROCESS_READ_WRITE_BARRIER; |
|
||||
return val; |
|
||||
} |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ winapi::interlocked_exchange(reinterpret_cast<volatile long*>(mem), (long)val); } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with": what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ return (boost::uint32_t)winapi::interlocked_compare_exchange(reinterpret_cast<volatile long*>(mem), (long)with, (long)cmp); } |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(_CRAYC)
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ |
|
||||
boost::uint32_t prev = cmp; |
|
||||
// This version by Mans Rullgard of Pathscale
|
|
||||
__asm__ __volatile__ ( "lock\n\t" |
|
||||
"cmpxchg %2,%0" |
|
||||
: "+m"(*mem), "+a"(prev) |
|
||||
: "r"(with) |
|
||||
: "cc"); |
|
||||
|
|
||||
return prev; |
|
||||
} |
|
||||
|
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ |
|
||||
// int r = *pw;
|
|
||||
// *mem += val;
|
|
||||
// return r;
|
|
||||
boost::uint32_t r; |
|
||||
|
|
||||
asm volatile |
|
||||
( |
|
||||
"lock\n\t" |
|
||||
"xadd %1, %0": |
|
||||
"+m"( *mem ), "=r"( r ): // outputs (%0, %1)
|
|
||||
"1"( val ): // inputs (%2 == %1)
|
|
||||
"memory", "cc" // clobbers
|
|
||||
); |
|
||||
|
|
||||
return r; |
|
||||
} |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, 1); } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, (boost::uint32_t)-1); } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ |
|
||||
const boost::uint32_t val = *mem; |
|
||||
__asm__ __volatile__ ( "" ::: "memory" ); |
|
||||
return val; |
|
||||
} |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ |
|
||||
__asm__ __volatile__ |
|
||||
( |
|
||||
"xchgl %0, %1" |
|
||||
: "+r" (val), "+m" (*mem) |
|
||||
:: "memory" |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#elif defined(__GNUC__) && (defined(__PPC__) || defined(__ppc__))
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ |
|
||||
boost::uint32_t prev, temp; |
|
||||
|
|
||||
asm volatile |
|
||||
( |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_LABEL("1") |
|
||||
"lwarx %0,0,%2\n\t" |
|
||||
"add %1,%0,%3\n\t" |
|
||||
"stwcx. %1,0,%2\n\t" |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-12") |
|
||||
: "=&r" (prev), "=&r" (temp) |
|
||||
: "b" (mem), "r" (val) |
|
||||
: "cc", "memory" |
|
||||
); |
|
||||
return prev; |
|
||||
} |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ |
|
||||
boost::uint32_t prev; |
|
||||
|
|
||||
asm volatile |
|
||||
( |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_LABEL("1") |
|
||||
"lwarx %0,0,%1\n\t" |
|
||||
"cmpw %0,%3\n\t" |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_JUMP("bne-", "2f", "+12") |
|
||||
"stwcx. %2,0,%1\n\t" |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_JUMP("bne-", "1b", "-16") |
|
||||
BOOST_INTERPROCESS_DETAIL_PPC_ASM_LABEL("2") |
|
||||
: "=&r"(prev) |
|
||||
: "b" (mem), "r" (with), "r" (cmp) |
|
||||
: "cc", "memory" |
|
||||
); |
|
||||
return prev; |
|
||||
} |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, 1); } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, boost::uint32_t(-1u)); } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ |
|
||||
const boost::uint32_t val = *mem; |
|
||||
__asm__ __volatile__ ( "" ::: "memory" ); |
|
||||
return val; |
|
||||
} |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ *mem = val; } |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#elif (defined(sun) || defined(__sun))
|
|
||||
|
|
||||
#include <atomic.h>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), (int32_t)val) - val; } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ return atomic_cas_32(reinterpret_cast<volatile ::uint32_t*>(mem), cmp, with); } |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), 1) - 1; } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add_32_nv(reinterpret_cast<volatile ::uint32_t*>(mem), (boost::uint32_t)-1) + 1; } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ return *mem; } |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ *mem = val; } |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#elif defined(__osf__) && defined(__DECCXX)
|
|
||||
|
|
||||
#include <machine/builtins.h>
|
|
||||
#include <c_asm.h>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically decrement a uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
//! Acquire, memory barrier after decrement.
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ boost::uint32_t old_val = __ATOMIC_DECREMENT_LONG(mem); __MB(); return old_val; } |
|
||||
|
|
||||
//! Atomically increment a uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
//! Release, memory barrier before increment.
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ __MB(); return __ATOMIC_INCREMENT_LONG(mem); } |
|
||||
|
|
||||
// Rational for the implementation of the atomic read and write functions.
|
|
||||
//
|
|
||||
// 1. The Alpha Architecture Handbook requires that access to a byte,
|
|
||||
// an aligned word, an aligned longword, or an aligned quadword is
|
|
||||
// atomic. (See 'Alpha Architecture Handbook', version 4, chapter 5.2.2.)
|
|
||||
//
|
|
||||
// 2. The CXX User's Guide states that volatile quantities are accessed
|
|
||||
// with single assembler instructions, and that a compilation error
|
|
||||
// occurs when declaring a quantity as volatile which is not properly
|
|
||||
// aligned.
|
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
//! Acquire, memory barrier after load.
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ boost::uint32_t old_val = *mem; __MB(); return old_val; } |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
//! Release, memory barrier before store.
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ __MB(); *mem = val; } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
//! Memory barrier between load and store.
|
|
||||
inline boost::uint32_t atomic_cas32( |
|
||||
volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ |
|
||||
// Note:
|
|
||||
//
|
|
||||
// Branch prediction prefers backward branches, and the Alpha Architecture
|
|
||||
// Handbook explicitely states that the loop should not be implemented like
|
|
||||
// it is below. (See chapter 4.2.5.) Therefore the code should probably look
|
|
||||
// like this:
|
|
||||
//
|
|
||||
// return asm(
|
|
||||
// "10: ldl_l %v0,(%a0) ;"
|
|
||||
// " cmpeq %v0,%a2,%t0 ;"
|
|
||||
// " beq %t0,20f ;"
|
|
||||
// " mb ;"
|
|
||||
// " mov %a1,%t0 ;"
|
|
||||
// " stl_c %t0,(%a0) ;"
|
|
||||
// " beq %t0,30f ;"
|
|
||||
// "20: ret ;"
|
|
||||
// "30: br 10b;",
|
|
||||
// mem, with, cmp);
|
|
||||
//
|
|
||||
// But as the compiler always transforms this into the form where a backward
|
|
||||
// branch is taken on failure, we can as well implement it in the straight
|
|
||||
// forward form, as this is what it will end up in anyway.
|
|
||||
|
|
||||
return asm( |
|
||||
"10: ldl_l %v0,(%a0) ;" // load prev value from mem and lock mem
|
|
||||
" cmpeq %v0,%a2,%t0 ;" // compare with given value
|
|
||||
" beq %t0,20f ;" // if not equal, we're done
|
|
||||
" mb ;" // memory barrier
|
|
||||
" mov %a1,%t0 ;" // load new value into scratch register
|
|
||||
" stl_c %t0,(%a0) ;" // store new value to locked mem (overwriting scratch)
|
|
||||
" beq %t0,10b ;" // store failed because lock has been stolen, retry
|
|
||||
"20: ", |
|
||||
mem, with, cmp); |
|
||||
} |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#elif defined(__IBMCPP__) && (__IBMCPP__ >= 800) && defined(_AIX)
|
|
||||
|
|
||||
#include <builtins.h>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//first define boost::uint32_t versions of __lwarx and __stwcx to avoid poluting
|
|
||||
//all the functions with casts
|
|
||||
|
|
||||
//! From XLC documenation :
|
|
||||
//! This function can be used with a subsequent stwcxu call to implement a
|
|
||||
//! read-modify-write on a specified memory location. The two functions work
|
|
||||
//! together to ensure that if the store is successfully performed, no other
|
|
||||
//! processor or mechanism can modify the target doubleword between the time
|
|
||||
//! lwarxu function is executed and the time the stwcxu functio ncompletes.
|
|
||||
//! "mem" : pointer to the object
|
|
||||
//! Returns the value at pointed to by mem
|
|
||||
inline boost::uint32_t lwarxu(volatile boost::uint32_t *mem) |
|
||||
{ |
|
||||
return static_cast<boost::uint32_t>(__lwarx(reinterpret_cast<volatile int*>(mem))); |
|
||||
} |
|
||||
|
|
||||
//! "mem" : pointer to the object
|
|
||||
//! "val" : the value to store
|
|
||||
//! Returns true if the update of mem is successful and false if it is
|
|
||||
//!unsuccessful
|
|
||||
inline bool stwcxu(volatile boost::uint32_t* mem, boost::uint32_t val) |
|
||||
{ |
|
||||
return (__stwcx(reinterpret_cast<volatile int*>(mem), static_cast<int>(val)) != 0); |
|
||||
} |
|
||||
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ |
|
||||
boost::uint32_t oldValue; |
|
||||
do |
|
||||
{ |
|
||||
oldValue = lwarxu(mem); |
|
||||
}while (!stwcxu(mem, oldValue+val)); |
|
||||
return oldValue; |
|
||||
} |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, 1); } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, (boost::uint32_t)-1); } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ return *mem; } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ |
|
||||
boost::uint32_t oldValue; |
|
||||
boost::uint32_t valueToStore; |
|
||||
do |
|
||||
{ |
|
||||
oldValue = lwarxu(mem); |
|
||||
} while (!stwcxu(mem, (oldValue == with) ? cmp : oldValue)); |
|
||||
|
|
||||
return oldValue; |
|
||||
} |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ *mem = val; } |
|
||||
|
|
||||
} //namespace ipcdetail
|
|
||||
} //namespace interprocess
|
|
||||
} //namespace boost
|
|
||||
|
|
||||
#elif defined(__GNUC__) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ return __sync_fetch_and_add(const_cast<boost::uint32_t *>(mem), val); } |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, 1); } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return atomic_add32(mem, (boost::uint32_t)-1); } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ boost::uint32_t old_val = *mem; __sync_synchronize(); return old_val; } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ return __sync_val_compare_and_swap(const_cast<boost::uint32_t *>(mem), cmp, with); } |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ __sync_synchronize(); *mem = val; } |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
#elif defined(__VXWORKS__)
|
|
||||
|
|
||||
#include <vxAtomicLib.h>
|
|
||||
// VxWorks atomic32_t is not volatile, for some unknown reason
|
|
||||
#define vx_atomic_cast(_i) (reinterpret_cast< ::atomic32_t *>( const_cast<boost::uint32_t *>(_i)))
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//! Atomically add 'val' to an boost::uint32_t
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "val": amount to add
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_add32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ return ::vxAtomic32Add( vx_atomic_cast(mem), val); } |
|
||||
|
|
||||
//! Atomically increment an apr_uint32_t by 1
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_inc32(volatile boost::uint32_t *mem) |
|
||||
{ return ::vxAtomic32Inc( vx_atomic_cast(mem) ); } |
|
||||
|
|
||||
//! Atomically decrement an boost::uint32_t by 1
|
|
||||
//! "mem": pointer to the atomic value
|
|
||||
//! Returns the old value pointed to by mem
|
|
||||
inline boost::uint32_t atomic_dec32(volatile boost::uint32_t *mem) |
|
||||
{ return ::vxAtomic32Dec( vx_atomic_cast(mem) ); } |
|
||||
|
|
||||
//! Atomically read an boost::uint32_t from memory
|
|
||||
inline boost::uint32_t atomic_read32(volatile boost::uint32_t *mem) |
|
||||
{ return ::vxAtomic32Get( vx_atomic_cast(mem) ); } |
|
||||
|
|
||||
//! Compare an boost::uint32_t's value with "cmp".
|
|
||||
//! If they are the same swap the value with "with"
|
|
||||
//! "mem": pointer to the value
|
|
||||
//! "with" what to swap it with
|
|
||||
//! "cmp": the value to compare it to
|
|
||||
//! Returns the old value of *mem
|
|
||||
inline boost::uint32_t atomic_cas32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t with, boost::uint32_t cmp) |
|
||||
{ return ::vxAtomic32Cas( vx_atomic_cast(mem), cmp, with); } |
|
||||
|
|
||||
//! Atomically set an boost::uint32_t in memory
|
|
||||
//! "mem": pointer to the object
|
|
||||
//! "param": val value that the object will assume
|
|
||||
inline void atomic_write32(volatile boost::uint32_t *mem, boost::uint32_t val) |
|
||||
{ ::vxAtomic32Set( vx_atomic_cast(mem), val); } |
|
||||
|
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#else
|
|
||||
|
|
||||
#error No atomic operations implemented for this platform, sorry!
|
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
inline bool atomic_add_unless32 |
|
||||
(volatile boost::uint32_t *mem, boost::uint32_t value, boost::uint32_t unless_this) |
|
||||
{ |
|
||||
boost::uint32_t old, c(atomic_read32(mem)); |
|
||||
while(c != unless_this && (old = atomic_cas32(mem, c + value, c)) != c){ |
|
||||
c = old; |
|
||||
} |
|
||||
return c != unless_this; |
|
||||
} |
|
||||
|
|
||||
} //namespace ipcdetail
|
|
||||
} //namespace interprocess
|
|
||||
} //namespace boost
|
|
||||
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_ATOMIC_HPP
|
|
@ -1,31 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_CAST_TAGS_HPP
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_CAST_TAGS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost { namespace interprocess { namespace ipcdetail { |
|
||||
|
|
||||
struct static_cast_tag {}; |
|
||||
struct const_cast_tag {}; |
|
||||
struct dynamic_cast_tag {}; |
|
||||
struct reinterpret_cast_tag {}; |
|
||||
|
|
||||
}}} //namespace boost { namespace interprocess { namespace ipcdetail {
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_CAST_TAGS_HPP
|
|
@ -1,127 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2020-2021. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <cwchar>
|
|
||||
#include <cstring>
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
|
|
||||
class char_wchar_holder |
|
||||
{ |
|
||||
public: |
|
||||
char_wchar_holder() |
|
||||
: m_str(), m_is_wide() |
|
||||
{ |
|
||||
m_str.n = 0; |
|
||||
} |
|
||||
|
|
||||
char_wchar_holder(const char *nstr) |
|
||||
: m_str(), m_is_wide() |
|
||||
{ |
|
||||
m_str.n = new char [std::strlen(nstr)+1]; |
|
||||
std::strcpy(m_str.n, nstr); |
|
||||
} |
|
||||
|
|
||||
char_wchar_holder(const wchar_t *wstr) |
|
||||
: m_str(), m_is_wide(true) |
|
||||
{ |
|
||||
m_str.w = new wchar_t [std::wcslen(wstr)+1]; |
|
||||
std::wcscpy(m_str.w, wstr); |
|
||||
} |
|
||||
|
|
||||
char_wchar_holder& operator=(const char *nstr) |
|
||||
{ |
|
||||
char *tmp = new char [std::strlen(nstr)+1]; |
|
||||
this->delete_mem(); |
|
||||
m_str.n = tmp; |
|
||||
std::strcpy(m_str.n, nstr); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
char_wchar_holder& operator=(const wchar_t *wstr) |
|
||||
{ |
|
||||
wchar_t *tmp = new wchar_t [std::wcslen(wstr)+1]; |
|
||||
this->delete_mem(); |
|
||||
m_str.w = tmp; |
|
||||
std::wcscpy(m_str.w, wstr); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
char_wchar_holder& operator=(const char_wchar_holder &other) |
|
||||
{ |
|
||||
if (other.m_is_wide) |
|
||||
*this = other.getn(); |
|
||||
else |
|
||||
*this = other.getw(); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
~char_wchar_holder() |
|
||||
{ |
|
||||
this->delete_mem(); |
|
||||
} |
|
||||
|
|
||||
wchar_t *getw() const |
|
||||
{ return m_is_wide ? m_str.w : 0; } |
|
||||
|
|
||||
char *getn() const |
|
||||
{ return !m_is_wide ? m_str.n : 0; } |
|
||||
|
|
||||
void swap(char_wchar_holder& other) |
|
||||
{ |
|
||||
char_wchar tmp; |
|
||||
std::memcpy(&tmp, &m_str, sizeof(char_wchar)); |
|
||||
std::memcpy(&m_str, &other.m_str, sizeof(char_wchar)); |
|
||||
std::memcpy(&other.m_str, &tmp, sizeof(char_wchar)); |
|
||||
//
|
|
||||
bool b_tmp(m_is_wide); |
|
||||
m_is_wide = other.m_is_wide; |
|
||||
other.m_is_wide = b_tmp; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
void delete_mem() |
|
||||
{ |
|
||||
if(m_is_wide) |
|
||||
delete [] m_str.w; |
|
||||
else |
|
||||
delete [] m_str.n; |
|
||||
} |
|
||||
|
|
||||
union char_wchar |
|
||||
{ |
|
||||
char *n; |
|
||||
wchar_t *w; |
|
||||
} m_str; |
|
||||
bool m_is_wide; |
|
||||
}; |
|
||||
|
|
||||
} //namespace interprocess {
|
|
||||
} //namespace boost {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_INTERPROCESS_DETAIL_CHAR_WCHAR_HOLDER_HPP
|
|
@ -1,50 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_INTERPROCESS_CONFIG_INCLUDED
|
|
||||
#define BOOST_INTERPROCESS_CONFIG_INCLUDED
|
|
||||
#include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#ifdef BOOST_MSVC
|
|
||||
#pragma warning (push)
|
|
||||
#pragma warning (disable : 4702) // unreachable code
|
|
||||
#pragma warning (disable : 4706) // assignment within conditional expression
|
|
||||
#pragma warning (disable : 4127) // conditional expression is constant
|
|
||||
#pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
|
||||
#pragma warning (disable : 4284) // odd return type for operator->
|
|
||||
#pragma warning (disable : 4244) // possible loss of data
|
|
||||
#pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2"
|
|
||||
#pragma warning (disable : 4267) // conversion from "X" to "Y", possible loss of data
|
|
||||
#pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier"
|
|
||||
#pragma warning (disable : 4355) // "this" : used in base member initializer list
|
|
||||
#pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
|
|
||||
#pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated
|
|
||||
#pragma warning (disable : 4511) // copy constructor could not be generated
|
|
||||
#pragma warning (disable : 4512) // assignment operator could not be generated
|
|
||||
#pragma warning (disable : 4514) // unreferenced inline removed
|
|
||||
#pragma warning (disable : 4521) // Disable "multiple copy constructors specified"
|
|
||||
#pragma warning (disable : 4522) // "class" : multiple assignment operators specified
|
|
||||
#pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter
|
|
||||
#pragma warning (disable : 4710) // function not inlined
|
|
||||
#pragma warning (disable : 4711) // function selected for automatic inline expansion
|
|
||||
#pragma warning (disable : 4786) // identifier truncated in debug info
|
|
||||
#pragma warning (disable : 4996) // "function": was declared deprecated
|
|
||||
#pragma warning (disable : 4197) // top-level volatile in cast is ignored
|
|
||||
#pragma warning (disable : 4541) // 'typeid' used on polymorphic type 'boost::exception'
|
|
||||
// with /GR-; unpredictable behavior may result
|
|
||||
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
|
|
||||
#pragma warning (disable : 4671) // the copy constructor is inaccessible
|
|
||||
#pragma warning (disable : 4250) // inherits 'x' via dominance
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic push
|
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||
#endif
|
|
@ -1,16 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#if defined BOOST_MSVC
|
|
||||
#pragma warning (pop)
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 40600)
|
|
||||
#pragma GCC diagnostic pop
|
|
||||
#endif
|
|
@ -1,23 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2012-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#ifndef BOOST_INTERPROCESS_EXTERNAL_CONFIG_INCLUDED
|
|
||||
#define BOOST_INTERPROCESS_EXTERNAL_CONFIG_INCLUDED
|
|
||||
#include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
|
|
||||
# pragma GCC diagnostic push
|
|
||||
# pragma GCC diagnostic ignored "-Wshadow"
|
|
||||
# pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
||||
# pragma GCC diagnostic ignored "-Wconversion"
|
|
||||
# if (BOOST_GCC >= 100000)
|
|
||||
# pragma GCC diagnostic ignored "-Warith-conversion"
|
|
||||
# endif
|
|
||||
#endif
|
|
@ -1,12 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2012-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 406)
|
|
||||
# pragma GCC diagnostic pop
|
|
||||
#endif
|
|
@ -1,302 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
|
|
||||
#define BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <sstream>
|
|
||||
#include <string>
|
|
||||
#include <sys/types.h>
|
|
||||
#include <sys/stat.h>
|
|
||||
#include <errno.h>
|
|
||||
#include <cstddef>
|
|
||||
#include <boost/interprocess/detail/os_file_functions.hpp>
|
|
||||
|
|
||||
#include <boost/interprocess/detail/shared_dir_helpers.hpp>
|
|
||||
|
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
|
||||
|
|
||||
#include <fcntl.h>
|
|
||||
#include <io.h>
|
|
||||
#include <sys/locking.h>
|
|
||||
|
|
||||
#else //defined(BOOST_INTERPROCESS_WINDOWS)
|
|
||||
|
|
||||
#include <fcntl.h>
|
|
||||
#include <sys/stat.h>
|
|
||||
#include <unistd.h>
|
|
||||
|
|
||||
#endif //defined(BOOST_INTERPROCESS_WINDOWS)
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
#if defined(BOOST_INTERPROCESS_WINDOWS)
|
|
||||
|
|
||||
struct locking_file_serial_id |
|
||||
{ |
|
||||
int fd; |
|
||||
unsigned long dwVolumeSerialNumber; |
|
||||
unsigned long nFileIndexHigh; |
|
||||
unsigned long nFileIndexLow; |
|
||||
//This reference count counts the number of modules attached
|
|
||||
//to the shared memory and lock file. This serves to unlink
|
|
||||
//the locking file and shared memory when all modules are
|
|
||||
//done with the global memory (shared memory)
|
|
||||
volatile boost::uint32_t modules_attached_to_gmem_count; |
|
||||
}; |
|
||||
|
|
||||
inline bool lock_locking_file(int fd) |
|
||||
{ |
|
||||
int ret = 0; |
|
||||
while(ret != 0 && errno == EDEADLK){ |
|
||||
ret = _locking(fd, _LK_LOCK, 1/*lock_file_contents_length()*/); |
|
||||
} |
|
||||
return 0 == ret; |
|
||||
} |
|
||||
|
|
||||
inline bool try_lock_locking_file(int fd) |
|
||||
{ |
|
||||
return 0 == _locking(fd, _LK_NBLCK , 1); |
|
||||
} |
|
||||
|
|
||||
inline int open_or_create_and_lock_file(const char *name) |
|
||||
{ |
|
||||
permissions p; |
|
||||
p.set_unrestricted(); |
|
||||
while(1){ |
|
||||
file_handle_t handle = create_or_open_file(name, read_write, p); |
|
||||
int fd = _open_osfhandle((intptr_t)handle, _O_TEXT); |
|
||||
if(fd < 0){ |
|
||||
close_file(handle); |
|
||||
return fd; |
|
||||
} |
|
||||
if(!try_lock_locking_file(fd)){ |
|
||||
_close(fd); |
|
||||
return -1; |
|
||||
} |
|
||||
struct _stat s; |
|
||||
if(0 == _stat(name, &s)){ |
|
||||
return fd; |
|
||||
} |
|
||||
else{ |
|
||||
_close(fd); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
inline int try_open_and_lock_file(const char *name) |
|
||||
{ |
|
||||
file_handle_t handle = open_existing_file(name, read_write); |
|
||||
int fd = _open_osfhandle((intptr_t)handle, _O_TEXT); |
|
||||
if(fd < 0){ |
|
||||
close_file(handle); |
|
||||
return fd; |
|
||||
} |
|
||||
if(!try_lock_locking_file(fd)){ |
|
||||
_close(fd); |
|
||||
return -1; |
|
||||
} |
|
||||
return fd; |
|
||||
} |
|
||||
|
|
||||
inline void close_lock_file(int fd) |
|
||||
{ _close(fd); } |
|
||||
|
|
||||
inline bool is_valid_fd(int fd) |
|
||||
{ |
|
||||
struct _stat s; |
|
||||
return EBADF != _fstat(fd, &s); |
|
||||
} |
|
||||
|
|
||||
inline bool is_normal_file(int fd) |
|
||||
{ |
|
||||
if(_isatty(fd)) |
|
||||
return false; |
|
||||
struct _stat s; |
|
||||
if(0 != _fstat(fd, &s)) |
|
||||
return false; |
|
||||
return 0 != (s.st_mode & _S_IFREG); |
|
||||
} |
|
||||
|
|
||||
inline std::size_t get_size(int fd) |
|
||||
{ |
|
||||
struct _stat s; |
|
||||
if(0 != _fstat(fd, &s)) |
|
||||
return 0u; |
|
||||
return (std::size_t)s.st_size; |
|
||||
} |
|
||||
|
|
||||
inline bool fill_file_serial_id(int fd, locking_file_serial_id &id) |
|
||||
{ |
|
||||
winapi::interprocess_by_handle_file_information info; |
|
||||
if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info)) |
|
||||
return false; |
|
||||
id.fd = fd; |
|
||||
id.dwVolumeSerialNumber = info.dwVolumeSerialNumber; |
|
||||
id.nFileIndexHigh = info.nFileIndexHigh; |
|
||||
id.nFileIndexLow = info.nFileIndexLow; |
|
||||
id.modules_attached_to_gmem_count = 1; //Initialize attached count
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
inline bool compare_file_serial(int fd, const locking_file_serial_id &id) |
|
||||
{ |
|
||||
winapi::interprocess_by_handle_file_information info; |
|
||||
if(!winapi::get_file_information_by_handle((void*)_get_osfhandle(fd), &info)) |
|
||||
return false; |
|
||||
|
|
||||
return id.dwVolumeSerialNumber == info.dwVolumeSerialNumber && |
|
||||
id.nFileIndexHigh == info.nFileIndexHigh && |
|
||||
id.nFileIndexLow == info.nFileIndexLow; |
|
||||
} |
|
||||
|
|
||||
#else //UNIX
|
|
||||
|
|
||||
struct locking_file_serial_id |
|
||||
{ |
|
||||
int fd; |
|
||||
dev_t st_dev; |
|
||||
ino_t st_ino; |
|
||||
//This reference count counts the number of modules attached
|
|
||||
//to the shared memory and lock file. This serves to unlink
|
|
||||
//the locking file and shared memory when all modules are
|
|
||||
//done with the global memory (shared memory)
|
|
||||
volatile boost::uint32_t modules_attached_to_gmem_count; |
|
||||
}; |
|
||||
|
|
||||
inline bool lock_locking_file(int fd) |
|
||||
{ |
|
||||
int ret = 0; |
|
||||
while(ret != 0 && errno != EINTR){ |
|
||||
struct flock lock; |
|
||||
lock.l_type = F_WRLCK; |
|
||||
lock.l_whence = SEEK_SET; |
|
||||
lock.l_start = 0; |
|
||||
lock.l_len = 1; |
|
||||
ret = fcntl (fd, F_SETLKW, &lock); |
|
||||
} |
|
||||
return 0 == ret; |
|
||||
} |
|
||||
|
|
||||
inline bool try_lock_locking_file(int fd) |
|
||||
{ |
|
||||
struct flock lock; |
|
||||
lock.l_type = F_WRLCK; |
|
||||
lock.l_whence = SEEK_SET; |
|
||||
lock.l_start = 0; |
|
||||
lock.l_len = 1; |
|
||||
return 0 == fcntl (fd, F_SETLK, &lock); |
|
||||
} |
|
||||
|
|
||||
inline int open_or_create_and_lock_file(const char *name) |
|
||||
{ |
|
||||
permissions p; |
|
||||
p.set_unrestricted(); |
|
||||
while(1){ |
|
||||
int fd = create_or_open_file(name, read_write, p); |
|
||||
if(fd < 0){ |
|
||||
return fd; |
|
||||
} |
|
||||
if(!try_lock_locking_file(fd)){ |
|
||||
close(fd); |
|
||||
return -1; |
|
||||
} |
|
||||
struct stat s; |
|
||||
if(0 == stat(name, &s)){ |
|
||||
return fd; |
|
||||
} |
|
||||
else{ |
|
||||
close(fd); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
inline int try_open_and_lock_file(const char *name) |
|
||||
{ |
|
||||
int fd = open_existing_file(name, read_write); |
|
||||
if(fd < 0){ |
|
||||
return fd; |
|
||||
} |
|
||||
if(!try_lock_locking_file(fd)){ |
|
||||
close(fd); |
|
||||
return -1; |
|
||||
} |
|
||||
return fd; |
|
||||
} |
|
||||
|
|
||||
inline void close_lock_file(int fd) |
|
||||
{ close(fd); } |
|
||||
|
|
||||
inline bool is_valid_fd(int fd) |
|
||||
{ |
|
||||
struct stat s; |
|
||||
return EBADF != fstat(fd, &s); |
|
||||
} |
|
||||
|
|
||||
inline bool is_normal_file(int fd) |
|
||||
{ |
|
||||
struct stat s; |
|
||||
if(0 != fstat(fd, &s)) |
|
||||
return false; |
|
||||
return 0 != (s.st_mode & S_IFREG); |
|
||||
} |
|
||||
|
|
||||
inline std::size_t get_size(int fd) |
|
||||
{ |
|
||||
struct stat s; |
|
||||
if(0 != fstat(fd, &s)) |
|
||||
return 0u; |
|
||||
return (std::size_t)s.st_size; |
|
||||
} |
|
||||
|
|
||||
inline bool fill_file_serial_id(int fd, locking_file_serial_id &id) |
|
||||
{ |
|
||||
struct stat s; |
|
||||
if(0 != fstat(fd, &s)) |
|
||||
return false; |
|
||||
id.fd = fd; |
|
||||
id.st_dev = s.st_dev; |
|
||||
id.st_ino = s.st_ino; |
|
||||
id.modules_attached_to_gmem_count = 1; //Initialize attached count
|
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
inline bool compare_file_serial(int fd, const locking_file_serial_id &id) |
|
||||
{ |
|
||||
struct stat info; |
|
||||
if(0 != fstat(fd, &info)) |
|
||||
return false; |
|
||||
|
|
||||
return id.st_dev == info.st_dev && |
|
||||
id.st_ino == info.st_ino; |
|
||||
} |
|
||||
|
|
||||
#endif
|
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //BOOST_INTERPROCESS_FILE_LOCKING_HELPERS_HPP
|
|
@ -1,77 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
|
||||
#define BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
#include <boost/interprocess/detail/type_traits.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp> //alignment_of, aligned_storage
|
|
||||
#include <typeinfo> //typeid
|
|
||||
|
|
||||
//!\file
|
|
||||
//!Describes an abstract interface for placement construction and destruction.
|
|
||||
|
|
||||
namespace boost { |
|
||||
namespace interprocess { |
|
||||
namespace ipcdetail { |
|
||||
|
|
||||
struct in_place_interface |
|
||||
{ |
|
||||
in_place_interface(std::size_t alignm, std::size_t sz, const char *tname) |
|
||||
: alignment(alignm), size(sz), type_name(tname) |
|
||||
{} |
|
||||
|
|
||||
std::size_t alignment; |
|
||||
std::size_t size; |
|
||||
const char *type_name; |
|
||||
|
|
||||
virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed) = 0; |
|
||||
virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed) = 0; |
|
||||
virtual ~in_place_interface(){} |
|
||||
}; |
|
||||
|
|
||||
template<class T> |
|
||||
struct placement_destroy : public in_place_interface |
|
||||
{ |
|
||||
placement_destroy() |
|
||||
: in_place_interface(::boost::container::dtl::alignment_of<T>::value, sizeof(T), typeid(T).name()) |
|
||||
{} |
|
||||
|
|
||||
virtual void destroy_n(void *mem, std::size_t num, std::size_t &destroyed) BOOST_OVERRIDE |
|
||||
{ |
|
||||
T* memory = static_cast<T*>(mem); |
|
||||
for(destroyed = 0; destroyed < num; ++destroyed) |
|
||||
(memory++)->~T(); |
|
||||
} |
|
||||
|
|
||||
virtual void construct_n(void *, std::size_t, std::size_t &) BOOST_OVERRIDE {} |
|
||||
|
|
||||
private: |
|
||||
void destroy(void *mem) |
|
||||
{ static_cast<T*>(mem)->~T(); } |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} //namespace boost { namespace interprocess { namespace ipcdetail {
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_IN_PLACE_INTERFACE_HPP
|
|
@ -1,53 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_HPP
|
|
||||
#define BOOST_INTERPROCESS_INTERMODULE_SINGLETON_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
|
||||
#include <boost/interprocess/detail/windows_intermodule_singleton.hpp>
|
|
||||
#else
|
|
||||
#include <boost/interprocess/detail/portable_intermodule_singleton.hpp>
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
//Now this class is a singleton, initializing the singleton in
|
|
||||
//the first get() function call if LazyInit is true. If false
|
|
||||
//then the singleton will be initialized when loading the module.
|
|
||||
template<typename C, bool LazyInit = true, bool Phoenix = false> |
|
||||
class intermodule_singleton |
|
||||
#ifdef BOOST_INTERPROCESS_WINDOWS
|
|
||||
: public windows_intermodule_singleton<C, LazyInit, Phoenix> |
|
||||
#else
|
|
||||
: public portable_intermodule_singleton<C, LazyInit, Phoenix> |
|
||||
#endif
|
|
||||
{}; |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif
|
|
@ -1,505 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
|
|
||||
#define BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
#pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_begin.hpp>
|
|
||||
#include <boost/interprocess/detail/workaround.hpp>
|
|
||||
|
|
||||
#include <boost/interprocess/detail/atomic.hpp>
|
|
||||
#include <boost/interprocess/detail/os_thread_functions.hpp>
|
|
||||
#include <boost/interprocess/exceptions.hpp>
|
|
||||
#include <boost/container/detail/type_traits.hpp> //alignment_of, aligned_storage
|
|
||||
#include <boost/interprocess/detail/mpl.hpp>
|
|
||||
#include <boost/interprocess/sync/spin/wait.hpp>
|
|
||||
#include <boost/assert.hpp>
|
|
||||
#include <cstddef>
|
|
||||
#include <cstdio>
|
|
||||
#include <cstdlib>
|
|
||||
#include <cstring>
|
|
||||
#include <string>
|
|
||||
#include <typeinfo>
|
|
||||
#include <sstream>
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
namespace intermodule_singleton_helpers { |
|
||||
|
|
||||
inline void get_pid_creation_time_str(std::string &s) |
|
||||
{ |
|
||||
std::stringstream stream; |
|
||||
stream << get_current_process_id() << '_'; |
|
||||
stream.precision(6); |
|
||||
stream << std::fixed << get_current_process_creation_time(); |
|
||||
s = stream.str(); |
|
||||
} |
|
||||
|
|
||||
inline const char *get_map_base_name() |
|
||||
{ return "bip.gmem.map."; } |
|
||||
|
|
||||
inline void get_map_name(std::string &map_name) |
|
||||
{ |
|
||||
get_pid_creation_time_str(map_name); |
|
||||
map_name.insert(0, get_map_base_name()); |
|
||||
} |
|
||||
|
|
||||
inline std::size_t get_map_size() |
|
||||
{ return 65536; } |
|
||||
|
|
||||
template<class ThreadSafeGlobalMap> |
|
||||
struct thread_safe_global_map_dependant; |
|
||||
|
|
||||
} //namespace intermodule_singleton_helpers {
|
|
||||
|
|
||||
//This class contains common code for all singleton types, so that we instantiate this
|
|
||||
//code just once per module. This class also holds a thread soafe global map
|
|
||||
//to be used by all instances protected with a reference count
|
|
||||
template<class ThreadSafeGlobalMap> |
|
||||
class intermodule_singleton_common |
|
||||
{ |
|
||||
public: |
|
||||
typedef void*(singleton_constructor_t)(ThreadSafeGlobalMap &); |
|
||||
typedef void (singleton_destructor_t)(void *, ThreadSafeGlobalMap &); |
|
||||
|
|
||||
static const ::boost::uint32_t Uninitialized = 0u; |
|
||||
static const ::boost::uint32_t Initializing = 1u; |
|
||||
static const ::boost::uint32_t Initialized = 2u; |
|
||||
static const ::boost::uint32_t Broken = 3u; |
|
||||
static const ::boost::uint32_t Destroyed = 4u; |
|
||||
|
|
||||
//Initialize this_module_singleton_ptr, creates the global map if needed and also creates an unique
|
|
||||
//opaque type in global map through a singleton_constructor_t function call,
|
|
||||
//initializing the passed pointer to that unique instance.
|
|
||||
//
|
|
||||
//We have two concurrency types here. a)the global map/singleton creation must
|
|
||||
//be safe between threads of this process but in different modules/dlls. b)
|
|
||||
//the pointer to the singleton is per-module, so we have to protect this
|
|
||||
//initization between threads of the same module.
|
|
||||
//
|
|
||||
//All static variables declared here are shared between inside a module
|
|
||||
//so atomic operations will synchronize only threads of the same module.
|
|
||||
static void initialize_singleton_logic |
|
||||
(void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_constructor_t constructor, bool phoenix) |
|
||||
{ |
|
||||
//If current module is not initialized enter to lock free logic
|
|
||||
if(atomic_read32(&this_module_singleton_initialized) != Initialized){ |
|
||||
//Now a single thread of the module will succeed in this CAS.
|
|
||||
//trying to pass from Uninitialized to Initializing
|
|
||||
::boost::uint32_t previous_module_singleton_initialized = atomic_cas32 |
|
||||
(&this_module_singleton_initialized, Initializing, Uninitialized); |
|
||||
//If the thread succeeded the CAS (winner) it will compete with other
|
|
||||
//winner threads from other modules to create the global map
|
|
||||
if(previous_module_singleton_initialized == Destroyed){ |
|
||||
//Trying to resurrect a dead Phoenix singleton. Just try to
|
|
||||
//mark it as uninitialized and start again
|
|
||||
if(phoenix){ |
|
||||
atomic_cas32(&this_module_singleton_initialized, Uninitialized, Destroyed); |
|
||||
previous_module_singleton_initialized = atomic_cas32 |
|
||||
(&this_module_singleton_initialized, Initializing, Uninitialized); |
|
||||
} |
|
||||
//Trying to resurrect a non-Phoenix dead singleton is an error
|
|
||||
else{ |
|
||||
throw interprocess_exception("Boost.Interprocess: Dead reference on non-Phoenix singleton of type"); |
|
||||
} |
|
||||
} |
|
||||
if(previous_module_singleton_initialized == Uninitialized){ |
|
||||
BOOST_TRY{ |
|
||||
//Now initialize the global map, this function must solve concurrency
|
|
||||
//issues between threads of several modules
|
|
||||
initialize_global_map_handle(); |
|
||||
//Now try to create the singleton in global map.
|
|
||||
//This function solves concurrency issues
|
|
||||
//between threads of several modules
|
|
||||
ThreadSafeGlobalMap *const pmap = get_map_ptr(); |
|
||||
void *tmp = constructor(*pmap); |
|
||||
//Increment the module reference count that reflects how many
|
|
||||
//singletons this module holds, so that we can safely destroy
|
|
||||
//module global map object when no singleton is left
|
|
||||
atomic_inc32(&this_module_singleton_count); |
|
||||
//Insert a barrier before assigning the pointer to
|
|
||||
//make sure this assignment comes after the initialization
|
|
||||
atomic_write32(&this_module_singleton_initialized, Initializing); |
|
||||
//Assign the singleton address to the module-local pointer
|
|
||||
ptr = tmp; |
|
||||
//Memory barrier inserted, all previous operations should complete
|
|
||||
//before this one. Now marked as initialized
|
|
||||
atomic_write32(&this_module_singleton_initialized, Initialized); |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
//Mark singleton failed to initialize
|
|
||||
atomic_write32(&this_module_singleton_initialized, Broken); |
|
||||
BOOST_RETHROW |
|
||||
} BOOST_CATCH_END |
|
||||
} |
|
||||
//If previous state was initializing, this means that another winner thread is
|
|
||||
//trying to initialize the singleton. Just wait until completes its work.
|
|
||||
else if(previous_module_singleton_initialized == Initializing){ |
|
||||
spin_wait swait; |
|
||||
while(1){ |
|
||||
previous_module_singleton_initialized = atomic_read32(&this_module_singleton_initialized); |
|
||||
if(previous_module_singleton_initialized >= Initialized){ |
|
||||
//Already initialized, or exception thrown by initializer thread
|
|
||||
break; |
|
||||
} |
|
||||
else if(previous_module_singleton_initialized == Initializing){ |
|
||||
swait.yield(); |
|
||||
} |
|
||||
else{ |
|
||||
//This can't be happening!
|
|
||||
BOOST_ASSERT(0); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
else if(previous_module_singleton_initialized == Initialized){ |
|
||||
//Nothing to do here, the singleton is ready
|
|
||||
} |
|
||||
//If previous state was greater than initialized, then memory is broken
|
|
||||
//trying to initialize the singleton.
|
|
||||
else{//(previous_module_singleton_initialized > Initialized)
|
|
||||
throw interprocess_exception("boost::interprocess::intermodule_singleton initialization failed"); |
|
||||
} |
|
||||
} |
|
||||
BOOST_ASSERT(ptr != 0); |
|
||||
} |
|
||||
|
|
||||
static void finalize_singleton_logic(void *&ptr, volatile boost::uint32_t &this_module_singleton_initialized, singleton_destructor_t destructor) |
|
||||
{ |
|
||||
//Protect destruction against lazy singletons not initialized in this execution
|
|
||||
if(ptr){ |
|
||||
//Note: this destructor might provoke a Phoenix singleton
|
|
||||
//resurrection. This means that this_module_singleton_count
|
|
||||
//might change after this call.
|
|
||||
ThreadSafeGlobalMap * const pmap = get_map_ptr(); |
|
||||
destructor(ptr, *pmap); |
|
||||
ptr = 0; |
|
||||
|
|
||||
//Memory barrier to make sure pointer is nulled.
|
|
||||
//Mark this singleton as destroyed.
|
|
||||
atomic_write32(&this_module_singleton_initialized, Destroyed); |
|
||||
|
|
||||
//If this is the last singleton of this module
|
|
||||
//apply map destruction.
|
|
||||
//Note: singletons are destroyed when the module is unloaded
|
|
||||
//so no threads should be executing or holding references
|
|
||||
//to this module
|
|
||||
if(1 == atomic_dec32(&this_module_singleton_count)){ |
|
||||
destroy_global_map_handle(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
static ThreadSafeGlobalMap *get_map_ptr() |
|
||||
{ |
|
||||
return static_cast<ThreadSafeGlobalMap *>(static_cast<void*>(mem_holder.map_mem)); |
|
||||
} |
|
||||
|
|
||||
static void initialize_global_map_handle() |
|
||||
{ |
|
||||
//Obtain unique map name and size
|
|
||||
spin_wait swait; |
|
||||
while(1){ |
|
||||
//Try to pass map state to initializing
|
|
||||
::boost::uint32_t tmp = atomic_cas32(&this_module_map_initialized, Initializing, Uninitialized); |
|
||||
if(tmp == Initialized || tmp == Broken){ |
|
||||
break; |
|
||||
} |
|
||||
else if(tmp == Destroyed){ |
|
||||
tmp = atomic_cas32(&this_module_map_initialized, Uninitialized, Destroyed); |
|
||||
continue; |
|
||||
} |
|
||||
//If some other thread is doing the work wait
|
|
||||
else if(tmp == Initializing){ |
|
||||
swait.yield(); |
|
||||
} |
|
||||
else{ //(tmp == Uninitialized)
|
|
||||
//If not initialized try it again?
|
|
||||
BOOST_TRY{ |
|
||||
//Remove old global map from the system
|
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem(); |
|
||||
//in-place construction of the global map class
|
|
||||
ThreadSafeGlobalMap * const pmap = get_map_ptr(); |
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::construct_map(static_cast<void*>(pmap)); |
|
||||
//Use global map's internal lock to initialize the lock file
|
|
||||
//that will mark this gmem as "in use".
|
|
||||
typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>:: |
|
||||
lock_file_logic f(*pmap); |
|
||||
//If function failed (maybe a competing process has erased the shared
|
|
||||
//memory between creation and file locking), retry with a new instance.
|
|
||||
if(f.retry()){ |
|
||||
pmap->~ThreadSafeGlobalMap(); |
|
||||
atomic_write32(&this_module_map_initialized, Destroyed); |
|
||||
} |
|
||||
else{ |
|
||||
//Locking succeeded, so this global map module-instance is ready
|
|
||||
atomic_write32(&this_module_map_initialized, Initialized); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
//
|
|
||||
BOOST_RETHROW |
|
||||
} BOOST_CATCH_END |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static void destroy_global_map_handle() |
|
||||
{ |
|
||||
if(!atomic_read32(&this_module_singleton_count)){ |
|
||||
//This module is being unloaded, so destroy
|
|
||||
//the global map object of this module
|
|
||||
//and unlink the global map if it's the last
|
|
||||
ThreadSafeGlobalMap * const pmap = get_map_ptr(); |
|
||||
typename intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>:: |
|
||||
unlink_map_logic f(*pmap); |
|
||||
pmap->~ThreadSafeGlobalMap(); |
|
||||
atomic_write32(&this_module_map_initialized, Destroyed); |
|
||||
//Do some cleanup for other processes old gmem instances
|
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant<ThreadSafeGlobalMap>::remove_old_gmem(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
//Static data, zero-initalized without any dependencies
|
|
||||
//this_module_singleton_count is the number of singletons used by this module
|
|
||||
static volatile boost::uint32_t this_module_singleton_count; |
|
||||
|
|
||||
//this_module_map_initialized is the state of this module's map class object.
|
|
||||
//Values: Uninitialized, Initializing, Initialized, Broken
|
|
||||
static volatile boost::uint32_t this_module_map_initialized; |
|
||||
|
|
||||
//Raw memory to construct the global map manager
|
|
||||
static union mem_holder_t |
|
||||
{ |
|
||||
unsigned char map_mem [sizeof(ThreadSafeGlobalMap)]; |
|
||||
::boost::container::dtl::max_align_t aligner; |
|
||||
} mem_holder; |
|
||||
}; |
|
||||
|
|
||||
template<class ThreadSafeGlobalMap> |
|
||||
volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_singleton_count; |
|
||||
|
|
||||
template<class ThreadSafeGlobalMap> |
|
||||
volatile boost::uint32_t intermodule_singleton_common<ThreadSafeGlobalMap>::this_module_map_initialized; |
|
||||
|
|
||||
template<class ThreadSafeGlobalMap> |
|
||||
typename intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder_t |
|
||||
intermodule_singleton_common<ThreadSafeGlobalMap>::mem_holder; |
|
||||
|
|
||||
//A reference count to be stored in global map holding the number
|
|
||||
//of singletons (one per module) attached to the instance pointed by
|
|
||||
//the internal ptr.
|
|
||||
struct ref_count_ptr |
|
||||
{ |
|
||||
ref_count_ptr(void *p, boost::uint32_t count) |
|
||||
: ptr(p), singleton_ref_count(count) |
|
||||
{} |
|
||||
void *ptr; |
|
||||
//This reference count serves to count the number of attached
|
|
||||
//modules to this singleton
|
|
||||
volatile boost::uint32_t singleton_ref_count; |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
//Now this class is a singleton, initializing the singleton in
|
|
||||
//the first get() function call if LazyInit is true. If false
|
|
||||
//then the singleton will be initialized when loading the module.
|
|
||||
template<typename C, bool LazyInit, bool Phoenix, class ThreadSafeGlobalMap> |
|
||||
class intermodule_singleton_impl |
|
||||
{ |
|
||||
public: |
|
||||
|
|
||||
static C& get() //Let's make inlining easy
|
|
||||
{ |
|
||||
if(!this_module_singleton_ptr){ |
|
||||
if(lifetime.dummy_function()){ //This forces lifetime instantiation, for reference counted destruction
|
|
||||
atentry_work(); |
|
||||
} |
|
||||
} |
|
||||
return *static_cast<C*>(this_module_singleton_ptr); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
static void atentry_work() |
|
||||
{ |
|
||||
intermodule_singleton_common<ThreadSafeGlobalMap>::initialize_singleton_logic |
|
||||
(this_module_singleton_ptr, this_module_singleton_initialized, singleton_constructor, Phoenix); |
|
||||
} |
|
||||
|
|
||||
static void atexit_work() |
|
||||
{ |
|
||||
intermodule_singleton_common<ThreadSafeGlobalMap>::finalize_singleton_logic |
|
||||
(this_module_singleton_ptr, this_module_singleton_initialized, singleton_destructor); |
|
||||
} |
|
||||
|
|
||||
//These statics will be zero-initialized without any constructor call dependency
|
|
||||
//this_module_singleton_ptr will be a module-local pointer to the singleton
|
|
||||
static void* this_module_singleton_ptr; |
|
||||
|
|
||||
//this_module_singleton_count will be used to synchronize threads of the same module
|
|
||||
//for access to a singleton instance, and to flag the state of the
|
|
||||
//singleton.
|
|
||||
static volatile boost::uint32_t this_module_singleton_initialized; |
|
||||
|
|
||||
//This class destructor will trigger singleton destruction
|
|
||||
struct lifetime_type_lazy |
|
||||
{ |
|
||||
bool dummy_function() |
|
||||
{ return m_dummy == 0; } |
|
||||
|
|
||||
~lifetime_type_lazy() |
|
||||
{ |
|
||||
//if(!Phoenix){
|
|
||||
//atexit_work();
|
|
||||
//}
|
|
||||
} |
|
||||
|
|
||||
//Dummy volatile so that the compiler can't resolve its value at compile-time
|
|
||||
//and can't avoid lifetime_type instantiation if dummy_function() is called.
|
|
||||
static volatile int m_dummy; |
|
||||
}; |
|
||||
|
|
||||
struct lifetime_type_static |
|
||||
: public lifetime_type_lazy |
|
||||
{ |
|
||||
lifetime_type_static() |
|
||||
{ atentry_work(); } |
|
||||
}; |
|
||||
|
|
||||
typedef typename if_c |
|
||||
<LazyInit, lifetime_type_lazy, lifetime_type_static>::type lifetime_type; |
|
||||
|
|
||||
static lifetime_type lifetime; |
|
||||
|
|
||||
//A functor to be executed inside global map lock that just
|
|
||||
//searches for the singleton in map and if not present creates a new one.
|
|
||||
//If singleton constructor throws, the exception is propagated
|
|
||||
struct init_atomic_func |
|
||||
{ |
|
||||
init_atomic_func(ThreadSafeGlobalMap &m) |
|
||||
: m_map(m), ret_ptr() |
|
||||
{} |
|
||||
|
|
||||
void operator()() |
|
||||
{ |
|
||||
ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::find(m_map, typeid(C).name()); |
|
||||
if(!rcount){ |
|
||||
C *p = new C; |
|
||||
BOOST_TRY{ |
|
||||
ref_count_ptr val(p, 0u); |
|
||||
rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::insert(m_map, typeid(C).name(), val); |
|
||||
} |
|
||||
BOOST_CATCH(...){ |
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::erase(m_map, typeid(C).name()); |
|
||||
delete p; |
|
||||
BOOST_RETHROW |
|
||||
} BOOST_CATCH_END |
|
||||
} |
|
||||
//if(Phoenix){
|
|
||||
std::atexit(&atexit_work); |
|
||||
//}
|
|
||||
atomic_inc32(&rcount->singleton_ref_count); |
|
||||
ret_ptr = rcount->ptr; |
|
||||
} |
|
||||
void *data() const |
|
||||
{ return ret_ptr; } |
|
||||
|
|
||||
private: |
|
||||
ThreadSafeGlobalMap &m_map; |
|
||||
void *ret_ptr; |
|
||||
}; |
|
||||
|
|
||||
//A functor to be executed inside global map lock that just
|
|
||||
//deletes the singleton in map if the attached count reaches to zero
|
|
||||
struct fini_atomic_func |
|
||||
{ |
|
||||
fini_atomic_func(ThreadSafeGlobalMap &m) |
|
||||
: m_map(m) |
|
||||
{} |
|
||||
|
|
||||
void operator()() |
|
||||
{ |
|
||||
ref_count_ptr *rcount = intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::find(m_map, typeid(C).name()); |
|
||||
//The object must exist
|
|
||||
BOOST_ASSERT(rcount); |
|
||||
BOOST_ASSERT(rcount->singleton_ref_count > 0); |
|
||||
//Check if last reference
|
|
||||
if(atomic_dec32(&rcount->singleton_ref_count) == 1){ |
|
||||
//If last, destroy the object
|
|
||||
BOOST_ASSERT(rcount->ptr != 0); |
|
||||
C *pc = static_cast<C*>(rcount->ptr); |
|
||||
//Now destroy map entry
|
|
||||
bool destroyed = intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::erase(m_map, typeid(C).name()); |
|
||||
(void)destroyed; BOOST_ASSERT(destroyed == true); |
|
||||
delete pc; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
ThreadSafeGlobalMap &m_map; |
|
||||
}; |
|
||||
|
|
||||
//A wrapper to execute init_atomic_func
|
|
||||
static void *singleton_constructor(ThreadSafeGlobalMap &map) |
|
||||
{ |
|
||||
init_atomic_func f(map); |
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::atomic_func(map, f); |
|
||||
return f.data(); |
|
||||
} |
|
||||
|
|
||||
//A wrapper to execute fini_atomic_func
|
|
||||
static void singleton_destructor(void *p, ThreadSafeGlobalMap &map) |
|
||||
{ (void)p; |
|
||||
fini_atomic_func f(map); |
|
||||
intermodule_singleton_helpers::thread_safe_global_map_dependant |
|
||||
<ThreadSafeGlobalMap>::atomic_func(map, f); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template <typename C, bool L, bool P, class ThreadSafeGlobalMap> |
|
||||
volatile int intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type_lazy::m_dummy = 0; |
|
||||
|
|
||||
//These will be zero-initialized by the loader
|
|
||||
template <typename C, bool L, bool P, class ThreadSafeGlobalMap> |
|
||||
void *intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_ptr = 0; |
|
||||
|
|
||||
template <typename C, bool L, bool P, class ThreadSafeGlobalMap> |
|
||||
volatile boost::uint32_t intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::this_module_singleton_initialized = 0; |
|
||||
|
|
||||
template <typename C, bool L, bool P, class ThreadSafeGlobalMap> |
|
||||
typename intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime_type |
|
||||
intermodule_singleton_impl<C, L, P, ThreadSafeGlobalMap>::lifetime; |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#include <boost/interprocess/detail/config_end.hpp>
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_INTERMODULE_SINGLETON_COMMON_HPP
|
|
@ -1,39 +0,0 @@ |
|||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
//
|
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012. 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 http://www.boost.org/libs/interprocess for documentation.
|
|
||||
//
|
|
||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||
|
|
||||
#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
|
|
||||
#define BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
|
|
||||
|
|
||||
#ifndef BOOST_CONFIG_HPP
|
|
||||
# include <boost/config.hpp>
|
|
||||
#endif
|
|
||||
#
|
|
||||
#if defined(BOOST_HAS_PRAGMA_ONCE)
|
|
||||
# pragma once
|
|
||||
#endif
|
|
||||
|
|
||||
namespace boost{ |
|
||||
namespace interprocess{ |
|
||||
namespace ipcdetail{ |
|
||||
|
|
||||
class interprocess_tester |
|
||||
{ |
|
||||
public: |
|
||||
template<class T> |
|
||||
static void dont_close_on_destruction(T &t) |
|
||||
{ t.dont_close_on_destruction(); } |
|
||||
}; |
|
||||
|
|
||||
} //namespace ipcdetail{
|
|
||||
} //namespace interprocess{
|
|
||||
} //namespace boost{
|
|
||||
|
|
||||
#endif //#ifndef BOOST_INTERPROCESS_DETAIL_INTERPROCESS_TESTER_HPP
|
|
||||
|
|
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save
Reference in new issue