libs/flyweight/test/test_custom_factory.cpp
/* Boost.Flyweight test of a custom factory. * * Copyright 2006-2008 Joaquin M Lopez Munoz. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * * See http://www.boost.org/libs/flyweight for library home page. */ #include "test_custom_factory.hpp" #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ #include <boost/flyweight/flyweight.hpp> #include <boost/flyweight/refcounted.hpp> #include <boost/flyweight/simple_locking.hpp> #include <boost/flyweight/static_holder.hpp> #include <boost/mpl/aux_/lambda_support.hpp> #include <list> #include "test_basic_template.hpp" using namespace boost::flyweights; /* Info on list-update containers: * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/lu_based_containers.html */ template<typename Entry,typename Key> class lu_factory_class:public factory_marker { struct entry_type { entry_type(const Entry& x_):x(x_),count(0){} Entry x; std::size_t count; }; typedef std::list<entry_type> container_type; public: typedef typename container_type::iterator handle_type; handle_type insert(const Entry& x) { handle_type h; for(h=cont.begin();h!=cont.end();++h){ if(static_cast<const Key&>(h->x)==static_cast<const Key&>(x)){ if(++(h->count)==10){ h->count=0; cont.splice(cont.begin(),cont,h); /* move to front */ } return h; } } cont.push_back(entry_type(x)); h=cont.end(); --h; return h; } void erase(handle_type h) { cont.erase(h); } const Entry& entry(handle_type h){return h->x;} private: container_type cont; public: typedef lu_factory_class type; BOOST_MPL_AUX_LAMBDA_SUPPORT(2,lu_factory_class,(Entry,Key)) }; struct lu_factory:factory_marker { template<typename Entry,typename Key> struct apply { typedef lu_factory_class<Entry,Key> type; }; }; struct custom_factory_flyweight_specifier1 { template<typename T> struct apply { typedef flyweight<T,lu_factory> type; }; }; struct custom_factory_flyweight_specifier2 { template<typename T> struct apply { typedef flyweight< T, lu_factory_class<boost::mpl::_1,boost::mpl::_2> > type; }; }; void test_custom_factory() { test_basic_template<custom_factory_flyweight_specifier1>(); test_basic_template<custom_factory_flyweight_specifier2>(); }





