1 /* Boost.Flyweight test of a custom factory.
2 *
3 * Copyright 2006-2008 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_custom_factory.hpp"
12
13 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
14 #include <boost/flyweight/flyweight.hpp>
15 #include <boost/flyweight/refcounted.hpp>
16 #include <boost/flyweight/simple_locking.hpp>
17 #include <boost/flyweight/static_holder.hpp>
18 #include <boost/mpl/aux_/lambda_support.hpp>
19 #include <list>
20 #include "test_basic_template.hpp"
21
22 using namespace boost::flyweights;
23
24 /* Info on list-update containers:
25 * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/lu_based_containers.html
26 */
27
28 template<typename Entry,typename Key>
29 class lu_factory_class:public factory_marker
30 {
31 struct entry_type
32 {
entry_typelu_factory_class::entry_type33 entry_type(const Entry& x_):x(x_),count(0){}
34
35 Entry x;
36 std::size_t count;
37 };
38
39 typedef std::list<entry_type> container_type;
40
41 public:
42 typedef typename container_type::iterator handle_type;
43
insert(const Entry & x)44 handle_type insert(const Entry& x)
45 {
46 handle_type h;
47 for(h=cont.begin();h!=cont.end();++h){
48 if(static_cast<const Key&>(h->x)==static_cast<const Key&>(x)){
49 if(++(h->count)==10){
50 h->count=0;
51 cont.splice(cont.begin(),cont,h); /* move to front */
52 }
53 return h;
54 }
55 }
56 cont.push_back(entry_type(x));
57 h=cont.end();
58 --h;
59 return h;
60 }
61
erase(handle_type h)62 void erase(handle_type h)
63 {
64 cont.erase(h);
65 }
66
entry(handle_type h)67 const Entry& entry(handle_type h){return h->x;}
68
69 private:
70 container_type cont;
71
72 public:
73 typedef lu_factory_class type;
74 BOOST_MPL_AUX_LAMBDA_SUPPORT(2,lu_factory_class,(Entry,Key))
75 };
76
77 struct lu_factory:factory_marker
78 {
79 template<typename Entry,typename Key>
80 struct apply
81 {
82 typedef lu_factory_class<Entry,Key> type;
83 };
84 };
85
86 struct custom_factory_flyweight_specifier1
87 {
88 template<typename T>
89 struct apply
90 {
91 typedef flyweight<T,lu_factory> type;
92 };
93 };
94
95 struct custom_factory_flyweight_specifier2
96 {
97 template<typename T>
98 struct apply
99 {
100 typedef flyweight<
101 T,
102 lu_factory_class<boost::mpl::_1,boost::mpl::_2>
103 > type;
104 };
105 };
106
test_custom_factory()107 void test_custom_factory()
108 {
109 test_basic_template<custom_factory_flyweight_specifier1>();
110 test_basic_template<custom_factory_flyweight_specifier2>();
111 }
112