summaryrefslogtreecommitdiff
path: root/libs/container/test/scoped_allocator_usage_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/container/test/scoped_allocator_usage_test.cpp')
-rw-r--r--libs/container/test/scoped_allocator_usage_test.cpp395
1 files changed, 395 insertions, 0 deletions
diff --git a/libs/container/test/scoped_allocator_usage_test.cpp b/libs/container/test/scoped_allocator_usage_test.cpp
new file mode 100644
index 0000000000..bb841a2c77
--- /dev/null
+++ b/libs/container/test/scoped_allocator_usage_test.cpp
@@ -0,0 +1,395 @@
+#include <boost/container/detail/config_begin.hpp>
+#include <memory>
+
+#include <boost/move/move.hpp>
+#include <boost/container/vector.hpp>
+#include <boost/container/deque.hpp>
+#include <boost/container/list.hpp>
+#include <boost/container/slist.hpp>
+#include <boost/container/stable_vector.hpp>
+#include <boost/container/flat_map.hpp>
+#include <boost/container/flat_set.hpp>
+#include <boost/container/map.hpp>
+#include <boost/container/set.hpp>
+#include <boost/container/detail/mpl.hpp>
+
+#include <boost/container/scoped_allocator.hpp>
+
+template <typename Ty>
+class SimpleAllocator
+{
+public:
+ typedef Ty value_type;
+ typedef typename std::allocator<Ty>::pointer pointer;
+ typedef typename std::allocator<Ty>::size_type size_type;
+
+ SimpleAllocator(int value)
+ : m_state(value)
+ {}
+
+ template <typename T>
+ SimpleAllocator(const SimpleAllocator<T> &other)
+ : m_state(other.m_state)
+ {}
+
+ pointer allocate(size_type n)
+ {
+ return m_allocator.allocate(n);
+ }
+
+ void deallocate(pointer p, size_type n)
+ {
+ m_allocator.deallocate(p, n);
+ }
+
+ int get_value() const
+ { return m_state; }
+
+ private:
+ int m_state;
+ std::allocator<Ty> m_allocator;
+
+ template <typename T> friend class SimpleAllocator;
+};
+
+class alloc_int
+{
+ private: // Not copyable
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE(alloc_int)
+
+ public:
+ typedef SimpleAllocator<int> allocator_type;
+
+ alloc_int(BOOST_RV_REF(alloc_int)other)
+ : m_value(other.m_value), m_allocator(boost::move(other.m_allocator))
+ {
+ other.m_value = -1;
+ }
+
+ alloc_int(BOOST_RV_REF(alloc_int)other, const allocator_type &allocator)
+ : m_value(other.m_value), m_allocator(allocator)
+ {
+ other.m_value = -1;
+ }
+
+ alloc_int(int value, const allocator_type &allocator)
+ : m_value(value), m_allocator(allocator)
+ {}
+
+ alloc_int & operator=(BOOST_RV_REF(alloc_int)other)
+ {
+ other.m_value = other.m_value;
+ return *this;
+ }
+
+ int get_allocator_state() const
+ { return m_allocator.get_value(); }
+
+ int get_value() const
+ { return m_value; }
+
+ friend bool operator < (const alloc_int &l, const alloc_int &r)
+ { return l.m_value < r.m_value; }
+
+ friend bool operator == (const alloc_int &l, const alloc_int &r)
+ { return l.m_value == r.m_value; }
+
+ private:
+ int m_value;
+ allocator_type m_allocator;
+};
+
+using namespace ::boost::container;
+
+//general allocator
+typedef scoped_allocator_adaptor<SimpleAllocator<alloc_int> > AllocIntAllocator;
+
+//[multi]map/set
+typedef std::pair<const alloc_int, alloc_int> MapNode;
+typedef scoped_allocator_adaptor<SimpleAllocator<MapNode> > MapAllocator;
+typedef map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> Map;
+typedef set<alloc_int, std::less<alloc_int>, AllocIntAllocator> Set;
+typedef multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> MultiMap;
+typedef multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> MultiSet;
+
+//[multi]flat_map/set
+typedef std::pair<alloc_int, alloc_int> FlatMapNode;
+typedef scoped_allocator_adaptor<SimpleAllocator<FlatMapNode> > FlatMapAllocator;
+typedef flat_map<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMap;
+typedef flat_set<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatSet;
+typedef flat_multimap<alloc_int, alloc_int, std::less<alloc_int>, MapAllocator> FlatMultiMap;
+typedef flat_multiset<alloc_int, std::less<alloc_int>, AllocIntAllocator> FlatMultiSet;
+
+//vector, deque, list, slist, stable_vector.
+typedef vector<alloc_int, AllocIntAllocator> Vector;
+typedef deque<alloc_int, AllocIntAllocator> Deque;
+typedef list<alloc_int, AllocIntAllocator> List;
+typedef slist<alloc_int, AllocIntAllocator> Slist;
+typedef stable_vector<alloc_int, AllocIntAllocator> StableVector;
+
+/////////
+//is_unique_assoc
+/////////
+
+template<class T>
+struct is_unique_assoc
+{
+ static const bool value = false;
+};
+
+template<class K, class V, class C, class A>
+struct is_unique_assoc< map<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_unique_assoc< flat_map<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_unique_assoc< set<V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_unique_assoc< flat_set<V, C, A> >
+{
+ static const bool value = true;
+};
+
+
+/////////
+//is_map
+/////////
+
+template<class T>
+struct is_map
+{
+ static const bool value = false;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< map<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< flat_map<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< multimap<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class K, class V, class C, class A>
+struct is_map< flat_multimap<K, V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class T>
+struct is_set
+{
+ static const bool value = false;
+};
+
+template<class V, class C, class A>
+struct is_set< set<V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< flat_set<V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< multiset<V, C, A> >
+{
+ static const bool value = true;
+};
+
+template<class V, class C, class A>
+struct is_set< flat_multiset<V, C, A> >
+{
+ static const bool value = true;
+};
+
+/////////
+//container_wrapper
+/////////
+
+template< class Container
+ , bool Assoc = is_set<Container>::value || is_map<Container>::value
+ , bool UniqueAssoc = is_unique_assoc<Container>::value
+ , bool Map = is_map<Container>::value
+ >
+struct container_wrapper
+ : public Container
+{
+ typedef typename Container::allocator_type allocator_type;
+
+ container_wrapper(const allocator_type &a)
+ : Container(a)
+ {}
+};
+
+template<class Container> //map
+struct container_wrapper<Container, true, true, true>
+ : public Container
+{
+ typedef typename Container::allocator_type allocator_type;
+ typedef typename Container::key_compare key_compare;
+ typedef typename Container::value_type value_type;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::iterator iterator;
+
+ container_wrapper(const allocator_type &a)
+ : Container(key_compare(), a)
+ {}
+
+ template<class Arg>
+ iterator emplace(const_iterator, const Arg &arg)
+ {
+ return this->Container::emplace(arg, arg).first;
+ }
+};
+
+template<class Container> //set
+struct container_wrapper<Container, true, true, false>
+ : public Container
+{
+ typedef typename Container::allocator_type allocator_type;
+ typedef typename Container::key_compare key_compare;
+ typedef typename Container::value_type value_type;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::iterator iterator;
+
+ container_wrapper(const allocator_type &a)
+ : Container(key_compare(), a)
+ {}
+
+ template<class Arg>
+ iterator emplace(const_iterator, const Arg &arg)
+ {
+ return this->Container::emplace(arg).first;
+ }
+};
+
+template<class Container> //multimap
+struct container_wrapper<Container, true, false, true>
+ : public Container
+{
+ typedef typename Container::value_type value_type;
+ typedef typename Container::key_compare key_compare;
+ typedef typename Container::allocator_type allocator_type;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::iterator iterator;
+
+ container_wrapper(const allocator_type &a)
+ : Container(key_compare(), a)
+ {}
+
+ template<class Arg>
+ iterator emplace(const_iterator, const Arg &arg)
+ {
+ return this->Container::emplace(arg, arg);
+ }
+};
+
+//multiset
+template<class Container> //multimap
+struct container_wrapper<Container, true, false, false>
+ : public Container
+{
+ typedef typename Container::value_type value_type;
+ typedef typename Container::key_compare key_compare;
+ typedef typename Container::allocator_type allocator_type;
+ typedef typename Container::const_iterator const_iterator;
+ typedef typename Container::iterator iterator;
+
+ container_wrapper(const allocator_type &a)
+ : Container(key_compare(), a)
+ {}
+
+ template<class Arg>
+ iterator emplace(const_iterator, const Arg &arg)
+ {
+ return this->Container::emplace(arg);
+ }
+};
+
+bool test_value_and_state_equals(const alloc_int &r, int value, int state)
+{ return r.get_value() == value && r.get_allocator_state() == state; }
+
+template<class F, class S>
+bool test_value_and_state_equals(const container_detail::pair<F, S> &p, int value, int state)
+{ return test_value_and_state_equals(p.first, value, state) && test_alloc_state_equals(p.second, value, state); }
+
+template<class F, class S>
+bool test_value_and_state_equals(const std::pair<F, S> &p, int value, int state)
+{ return test_value_and_state_equals(p.first, value, state) && test_value_and_state_equals(p.second, value, state); }
+
+template<class Container>
+bool one_level_allocator_propagation_test()
+{
+ typedef container_wrapper<Container> ContainerWrapper;
+ typedef typename ContainerWrapper::iterator iterator;
+ ContainerWrapper c(SimpleAllocator<MapNode>(5));
+
+ c.clear();
+ iterator it = c.emplace(c.cbegin(), 42);
+
+ if(!test_value_and_state_equals(*it, 42, 5))
+ return false;
+
+ return true;
+}
+
+int main()
+{
+ //unique assoc
+ if(!one_level_allocator_propagation_test<FlatMap>())
+ return 1;
+ if(!one_level_allocator_propagation_test<Map>())
+ return 1;
+ if(!one_level_allocator_propagation_test<FlatSet>())
+ return 1;
+ if(!one_level_allocator_propagation_test<Set>())
+ return 1;
+ //multi assoc
+ if(!one_level_allocator_propagation_test<FlatMultiMap>())
+ return 1;
+ if(!one_level_allocator_propagation_test<MultiMap>())
+ return 1;
+ if(!one_level_allocator_propagation_test<FlatMultiSet>())
+ return 1;
+ if(!one_level_allocator_propagation_test<MultiSet>())
+ return 1;
+ //sequence containers
+ if(!one_level_allocator_propagation_test<Vector>())
+ return 1;
+ if(!one_level_allocator_propagation_test<Deque>())
+ return 1;
+ if(!one_level_allocator_propagation_test<List>())
+ return 1;
+ if(!one_level_allocator_propagation_test<Slist>())
+ return 1;
+ if(!one_level_allocator_propagation_test<StableVector>())
+ return 1;
+ return 0;
+}
+
+#include <boost/container/detail/config_end.hpp>