#include "../helpers/fwd.hpp"
#include "../helpers/memory.hpp"
-namespace test
-{
- struct allocator_false
+namespace test {
+ struct allocator_false
+ {
+ enum
{
- enum {
- is_select_on_copy = 0,
- is_propagate_on_swap = 0,
- is_propagate_on_assign = 0,
- is_propagate_on_move = 0,
- cxx11_construct = 0
- };
+ is_select_on_copy = 0,
+ is_propagate_on_swap = 0,
+ is_propagate_on_assign = 0,
+ is_propagate_on_move = 0,
+ cxx11_construct = 0
};
+ };
- struct allocator_flags_all
+ struct allocator_flags_all
+ {
+ enum
{
- enum {
- is_select_on_copy = 1,
- is_propagate_on_swap = 1,
- is_propagate_on_assign = 1,
- is_propagate_on_move = 1,
- cxx11_construct = 1
- };
+ is_select_on_copy = 1,
+ is_propagate_on_swap = 1,
+ is_propagate_on_assign = 1,
+ is_propagate_on_move = 1,
+ cxx11_construct = 1
};
-
- struct select_copy : allocator_false
- { enum { is_select_on_copy = 1 }; };
- struct propagate_swap : allocator_false
- { enum { is_propagate_on_swap = 1 }; };
- struct propagate_assign : allocator_false
- { enum { is_propagate_on_assign = 1 }; };
- struct propagate_move : allocator_false
- { enum { is_propagate_on_move = 1 }; };
-
- struct no_select_copy : allocator_flags_all
- { enum { is_select_on_copy = 0 }; };
- struct no_propagate_swap : allocator_flags_all
- { enum { is_propagate_on_swap = 0 }; };
- struct no_propagate_assign : allocator_flags_all
- { enum { is_propagate_on_assign = 0 }; };
- struct no_propagate_move : allocator_flags_all
- { enum { is_propagate_on_move = 0 }; };
-
- template <typename Flag>
- struct swap_allocator_base
+ };
+
+ struct select_copy : allocator_false
+ {
+ enum
+ {
+ is_select_on_copy = 1
+ };
+ };
+ struct propagate_swap : allocator_false
+ {
+ enum
+ {
+ is_propagate_on_swap = 1
+ };
+ };
+ struct propagate_assign : allocator_false
+ {
+ enum
{
- struct propagate_on_container_swap {
- enum { value = Flag::is_propagate_on_swap }; };
+ is_propagate_on_assign = 1
};
+ };
+ struct propagate_move : allocator_false
+ {
+ enum
+ {
+ is_propagate_on_move = 1
+ };
+ };
- template <typename Flag>
- struct assign_allocator_base
+ struct no_select_copy : allocator_flags_all
+ {
+ enum
+ {
+ is_select_on_copy = 0
+ };
+ };
+ struct no_propagate_swap : allocator_flags_all
+ {
+ enum
{
- struct propagate_on_container_copy_assignment {
- enum { value = Flag::is_propagate_on_assign }; };
+ is_propagate_on_swap = 0
};
+ };
+ struct no_propagate_assign : allocator_flags_all
+ {
+ enum
+ {
+ is_propagate_on_assign = 0
+ };
+ };
+ struct no_propagate_move : allocator_flags_all
+ {
+ enum
+ {
+ is_propagate_on_move = 0
+ };
+ };
- template <typename Flag>
- struct move_allocator_base
+ template <typename Flag> struct swap_allocator_base
+ {
+ struct propagate_on_container_swap
{
- struct propagate_on_container_move_assignment {
- enum { value = Flag::is_propagate_on_move }; };
+ enum
+ {
+ value = Flag::is_propagate_on_swap
+ };
};
+ };
- namespace
+ template <typename Flag> struct assign_allocator_base
+ {
+ struct propagate_on_container_copy_assignment
{
- // boostinspect:nounnamed
- bool force_equal_allocator_value = false;
- }
+ enum
+ {
+ value = Flag::is_propagate_on_assign
+ };
+ };
+ };
- struct force_equal_allocator
+ template <typename Flag> struct move_allocator_base
+ {
+ struct propagate_on_container_move_assignment
{
- bool old_value_;
-
- explicit force_equal_allocator(bool value)
- : old_value_(force_equal_allocator_value)
- { force_equal_allocator_value = value; }
-
- ~force_equal_allocator()
- { force_equal_allocator_value = old_value_; }
+ enum
+ {
+ value = Flag::is_propagate_on_move
+ };
};
+ };
+
+ namespace {
+ // boostinspect:nounnamed
+ bool force_equal_allocator_value = false;
+ }
- template <typename T>
- struct cxx11_allocator_base
+ struct force_equal_allocator
+ {
+ bool old_value_;
+
+ explicit force_equal_allocator(bool value)
+ : old_value_(force_equal_allocator_value)
{
- int tag_;
- int selected_;
-
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef T* pointer;
- typedef T const* const_pointer;
- typedef T& reference;
- typedef T const& const_reference;
- typedef T value_type;
-
- explicit cxx11_allocator_base(int t)
- : tag_(t), selected_(0)
- {
- detail::tracker.allocator_ref();
- }
-
- template <typename Y> cxx11_allocator_base(
- cxx11_allocator_base<Y> const& x)
- : tag_(x.tag_), selected_(x.selected_)
- {
- detail::tracker.allocator_ref();
- }
-
- cxx11_allocator_base(cxx11_allocator_base const& x)
- : tag_(x.tag_), selected_(x.selected_)
- {
- detail::tracker.allocator_ref();
- }
-
- ~cxx11_allocator_base()
- {
- detail::tracker.allocator_unref();
- }
-
- pointer address(reference r)
- {
- return pointer(&r);
- }
-
- const_pointer address(const_reference r)
- {
- return const_pointer(&r);
- }
-
- pointer allocate(size_type n) {
- pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
- detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
- return ptr;
- }
-
- pointer allocate(size_type n, void const*)
- {
- pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
- detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
- return ptr;
- }
-
- void deallocate(pointer p, size_type n)
- {
- // Only checking tags when propagating swap.
- // Note that tags will be tested
- // properly in the normal allocator.
- detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_,
- !force_equal_allocator_value);
- ::operator delete((void*) p);
- }
-
- void construct(T* p, T const& t) {
- detail::tracker.track_construct((void*) p, sizeof(T), tag_);
- new(p) T(t);
- }
+ force_equal_allocator_value = value;
+ }
-#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
- template<typename... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) {
- detail::tracker.track_construct((void*) p, sizeof(T), tag_);
- new(p) T(boost::forward<Args>(args)...);
- }
-#endif
+ ~force_equal_allocator() { force_equal_allocator_value = old_value_; }
+ };
- void destroy(T* p) {
- detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
- p->~T();
- }
+ template <typename T> struct cxx11_allocator_base
+ {
+ int tag_;
+ int selected_;
- size_type max_size() const {
- return (std::numeric_limits<size_type>::max)();
- }
- };
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef T const* const_pointer;
+ typedef T& reference;
+ typedef T const& const_reference;
+ typedef T value_type;
- template <typename T, typename Flags = propagate_swap,
- typename Enable = void>
- struct cxx11_allocator;
-
- template <typename T, typename Flags>
- struct cxx11_allocator<
- T, Flags,
- typename boost::disable_if_c<Flags::is_select_on_copy>::type
- > : public cxx11_allocator_base<T>,
- public swap_allocator_base<Flags>,
- public assign_allocator_base<Flags>,
- public move_allocator_base<Flags>,
- Flags
+ explicit cxx11_allocator_base(int t) : tag_(t), selected_(0)
{
-#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
- template <typename U> struct rebind {
- typedef cxx11_allocator<U, Flags> other;
- };
-#endif
+ detail::tracker.allocator_ref();
+ }
- explicit cxx11_allocator(int t = 0)
- : cxx11_allocator_base<T>(t)
- {
- }
-
- template <typename Y> cxx11_allocator(
- cxx11_allocator<Y, Flags> const& x)
- : cxx11_allocator_base<T>(x)
- {
- }
-
- cxx11_allocator(cxx11_allocator const& x)
- : cxx11_allocator_base<T>(x)
- {
- }
-
- // When not propagating swap, allocators are always equal
- // to avoid undefined behaviour.
- bool operator==(cxx11_allocator const& x) const
- {
- return force_equal_allocator_value || (this->tag_ == x.tag_);
- }
-
- bool operator!=(cxx11_allocator const& x) const
- {
- return !(*this == x);
- }
- };
+ template <typename Y>
+ cxx11_allocator_base(cxx11_allocator_base<Y> const& x)
+ : tag_(x.tag_), selected_(x.selected_)
+ {
+ detail::tracker.allocator_ref();
+ }
- template <typename T, typename Flags>
- struct cxx11_allocator<
- T, Flags,
- typename boost::enable_if_c<Flags::is_select_on_copy>::type
- > : public cxx11_allocator_base<T>,
- public swap_allocator_base<Flags>,
- public assign_allocator_base<Flags>,
- public move_allocator_base<Flags>,
- Flags
+ cxx11_allocator_base(cxx11_allocator_base const& x)
+ : tag_(x.tag_), selected_(x.selected_)
{
- cxx11_allocator select_on_container_copy_construction() const
- {
- cxx11_allocator tmp(*this);
- ++tmp.selected_;
- return tmp;
- }
+ detail::tracker.allocator_ref();
+ }
-#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
- template <typename U> struct rebind {
- typedef cxx11_allocator<U, Flags> other;
- };
+ ~cxx11_allocator_base() { detail::tracker.allocator_unref(); }
+
+ pointer address(reference r) { return pointer(&r); }
+
+ const_pointer address(const_reference r) { return const_pointer(&r); }
+
+ pointer allocate(size_type n)
+ {
+ pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
+ detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
+ return ptr;
+ }
+
+ pointer allocate(size_type n, void const*)
+ {
+ pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
+ detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
+ return ptr;
+ }
+
+ void deallocate(pointer p, size_type n)
+ {
+ // Only checking tags when propagating swap.
+ // Note that tags will be tested
+ // properly in the normal allocator.
+ detail::tracker.track_deallocate(
+ (void*)p, n, sizeof(T), tag_, !force_equal_allocator_value);
+ ::operator delete((void*)p);
+ }
+
+ void construct(T* p, T const& t)
+ {
+ detail::tracker.track_construct((void*)p, sizeof(T), tag_);
+ new (p) T(t);
+ }
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <typename... Args>
+ void construct(T* p, BOOST_FWD_REF(Args)... args)
+ {
+ detail::tracker.track_construct((void*)p, sizeof(T), tag_);
+ new (p) T(boost::forward<Args>(args)...);
+ }
#endif
- explicit cxx11_allocator(int t = 0)
- : cxx11_allocator_base<T>(t)
- {
- }
-
- template <typename Y> cxx11_allocator(
- cxx11_allocator<Y, Flags> const& x)
- : cxx11_allocator_base<T>(x)
- {
- }
-
- cxx11_allocator(cxx11_allocator const& x)
- : cxx11_allocator_base<T>(x)
- {
- }
-
- // When not propagating swap, allocators are always equal
- // to avoid undefined behaviour.
- bool operator==(cxx11_allocator const& x) const
- {
- return force_equal_allocator_value || (this->tag_ == x.tag_);
- }
-
- bool operator!=(cxx11_allocator const& x) const
- {
- return !(*this == x);
- }
+ void destroy(T* p)
+ {
+ detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
+ p->~T();
+ }
+
+ size_type max_size() const
+ {
+ return (std::numeric_limits<size_type>::max)();
+ }
+ };
+
+ template <typename T, typename Flags = propagate_swap, typename Enable = void>
+ struct cxx11_allocator;
+
+ template <typename T, typename Flags>
+ struct cxx11_allocator<T, Flags,
+ typename boost::disable_if_c<Flags::is_select_on_copy>::type>
+ : public cxx11_allocator_base<T>,
+ public swap_allocator_base<Flags>,
+ public assign_allocator_base<Flags>,
+ public move_allocator_base<Flags>,
+ Flags
+ {
+#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
+ template <typename U> struct rebind
+ {
+ typedef cxx11_allocator<U, Flags> other;
};
+#endif
+
+ explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
- template <typename T, typename Flags>
- bool equivalent_impl(
- cxx11_allocator<T, Flags> const& x,
- cxx11_allocator<T, Flags> const& y,
- test::derived_type)
+ template <typename Y>
+ cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
+ : cxx11_allocator_base<T>(x)
{
- return x.tag_ == y.tag_;
}
- // Function to check how many times an allocator has been selected,
- // return 0 for other allocators.
+ cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
+
+ // When not propagating swap, allocators are always equal
+ // to avoid undefined behaviour.
+ bool operator==(cxx11_allocator const& x) const
+ {
+ return force_equal_allocator_value || (this->tag_ == x.tag_);
+ }
- struct convert_from_anything
+ bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
+ };
+
+ template <typename T, typename Flags>
+ struct cxx11_allocator<T, Flags,
+ typename boost::enable_if_c<Flags::is_select_on_copy>::type>
+ : public cxx11_allocator_base<T>,
+ public swap_allocator_base<Flags>,
+ public assign_allocator_base<Flags>,
+ public move_allocator_base<Flags>,
+ Flags
+ {
+ cxx11_allocator select_on_container_copy_construction() const
+ {
+ cxx11_allocator tmp(*this);
+ ++tmp.selected_;
+ return tmp;
+ }
+
+#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
+ template <typename U> struct rebind
{
- template <typename T>
- convert_from_anything(T const&) {}
+ typedef cxx11_allocator<U, Flags> other;
};
+#endif
+
+ explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
- inline int selected_count(convert_from_anything)
+ template <typename Y>
+ cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
+ : cxx11_allocator_base<T>(x)
{
- return 0;
}
- template <typename T, typename Flags>
- int selected_count(cxx11_allocator<T, Flags> const& x)
+ cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
+
+ // When not propagating swap, allocators are always equal
+ // to avoid undefined behaviour.
+ bool operator==(cxx11_allocator const& x) const
{
- return x.selected_;
+ return force_equal_allocator_value || (this->tag_ == x.tag_);
}
+
+ bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
+ };
+
+ template <typename T, typename Flags>
+ bool equivalent_impl(cxx11_allocator<T, Flags> const& x,
+ cxx11_allocator<T, Flags> const& y, test::derived_type)
+ {
+ return x.tag_ == y.tag_;
+ }
+
+ // Function to check how many times an allocator has been selected,
+ // return 0 for other allocators.
+
+ struct convert_from_anything
+ {
+ template <typename T> convert_from_anything(T const&) {}
+ };
+
+ inline int selected_count(convert_from_anything) { return 0; }
+
+ template <typename T, typename Flags>
+ int selected_count(cxx11_allocator<T, Flags> const& x)
+ {
+ return x.selected_;
+ }
}
#endif