1 | /* Boost.Flyweight test of assoc_container_factory. |
2 | * |
3 | * Copyright 2006-2018 Joaquin M Lopez Munoz. |
4 | * Distributed under the Boost Software License, Version 1.0. |
5 | * (See accompanying file LICENSE_1_0.txt or copy at |
6 | * http://www.boost.org/LICENSE_1_0.txt) |
7 | * |
8 | * See http://www.boost.org/libs/flyweight for library home page. |
9 | */ |
10 | |
11 | #include "test_assoc_cont_factory.hpp" |
12 | |
13 | #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ |
14 | #include <boost/flyweight/assoc_container_factory.hpp> |
15 | #include <boost/flyweight/detail/is_placeholder_expr.hpp> |
16 | #include <boost/flyweight/flyweight.hpp> |
17 | #include <boost/flyweight/refcounted.hpp> |
18 | #include <boost/flyweight/simple_locking.hpp> |
19 | #include <boost/flyweight/static_holder.hpp> |
20 | #include <boost/mpl/if.hpp> |
21 | #include <functional> |
22 | #include <set> |
23 | #include "test_basic_template.hpp" |
24 | |
25 | using namespace boost::flyweights; |
26 | |
27 | struct reverse_set_specifier |
28 | { |
29 | template<typename Entry,typename Key> |
30 | struct apply |
31 | { |
32 | typedef std::set<Entry,std::greater<Key> > type; |
33 | }; |
34 | }; |
35 | |
36 | struct assoc_container_factory_flyweight_specifier1 |
37 | { |
38 | template<typename T> |
39 | struct apply |
40 | { |
41 | typedef flyweight< |
42 | T, |
43 | assoc_container_factory<reverse_set_specifier> |
44 | > type; |
45 | }; |
46 | }; |
47 | |
48 | /* flyweight<..., assoc_container_factory_class<std::set<...> >, ...> pulls |
49 | * the type std::set<...> in as part of its associated ADL set and causes it |
50 | * to be instantiated when doing any unqualified function call like, for |
51 | * instance, comparing flyweights for equality, which can trigger a static |
52 | * assertion in concept-checked STL implementations when std::set<...> is an |
53 | * MPL placeholder expression. We avoid this mess with protected_set<...>. |
54 | */ |
55 | |
56 | struct protected_set_empty_base{}; |
57 | |
58 | template<typename K,typename C,typename A> |
59 | struct protected_set: |
60 | boost::mpl::if_c< |
61 | boost::flyweights::detail::is_placeholder_expression< |
62 | protected_set<K,C,A> |
63 | >::value, |
64 | protected_set_empty_base, |
65 | std::set<K,C,A> |
66 | >::type |
67 | {}; |
68 | |
69 | struct assoc_container_factory_flyweight_specifier2 |
70 | { |
71 | template<typename T> |
72 | struct apply |
73 | { |
74 | typedef flyweight< |
75 | T, |
76 | assoc_container_factory_class< |
77 | protected_set< |
78 | boost::mpl::_1, |
79 | std::greater<boost::mpl::_2>, |
80 | std::allocator<boost::mpl::_1> |
81 | > |
82 | > |
83 | > type; |
84 | }; |
85 | }; |
86 | |
87 | void test_assoc_container_factory() |
88 | { |
89 | test_basic_template<assoc_container_factory_flyweight_specifier1>(); |
90 | test_basic_template<assoc_container_factory_flyweight_specifier2>(); |
91 | } |
92 | |