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