a5665e6ee1
[SVN r50320]
123 lines
3.4 KiB
C++
123 lines
3.4 KiB
C++
/* Boost.Flyweight example of 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.
|
|
*/
|
|
|
|
/* We include the default components of Boost.Flyweight except the factory,
|
|
* which will be provided by ourselves.
|
|
*/
|
|
#include <boost/flyweight/flyweight.hpp>
|
|
#include <boost/flyweight/factory_tag.hpp>
|
|
#include <boost/flyweight/static_holder.hpp>
|
|
#include <boost/flyweight/simple_locking.hpp>
|
|
#include <boost/flyweight/refcounted.hpp>
|
|
#include <boost/tokenizer.hpp>
|
|
#include <functional>
|
|
#include <iostream>
|
|
#include <set>
|
|
|
|
using namespace boost::flyweights;
|
|
|
|
/* custom factory based on std::set with some logging capabilities */
|
|
|
|
/* Entry is the type of the stored objects. Value is the type
|
|
* on which flyweight operates, that is, the T in flyweoght<T>. It
|
|
* is guaranteed that Entry implicitly converts to const Value&.
|
|
* The factory class could accept other template arguments (for
|
|
* instance, a comparison predicate for the values), we leave it like
|
|
* that for simplicity.
|
|
*/
|
|
|
|
template<typename Entry,typename Key>
|
|
class verbose_factory_class
|
|
{
|
|
/* Entry store. Since Entry is implicitly convertible to const Key&,
|
|
* we can directly use std::less<Key> as the comparer for std::set.
|
|
*/
|
|
|
|
typedef std::set<Entry,std::less<Key> > store_type;
|
|
|
|
store_type store;
|
|
|
|
public:
|
|
typedef typename store_type::iterator handle_type;
|
|
|
|
handle_type insert(const Entry& x)
|
|
{
|
|
/* locate equivalent entry or insert otherwise */
|
|
|
|
std::pair<handle_type, bool> p=store.insert(x);
|
|
if(p.second){ /* new entry */
|
|
std::cout<<"new: "<<(const Key&)x<<std::endl;
|
|
}
|
|
else{ /* existing entry */
|
|
std::cout<<"hit: "<<(const Key&)x<<std::endl;
|
|
}
|
|
return p.first;
|
|
}
|
|
|
|
void erase(handle_type h)
|
|
{
|
|
std::cout<<"del: "<<(const Key&)*h<<std::endl;
|
|
store.erase(h);
|
|
}
|
|
|
|
const Entry& entry(handle_type h)
|
|
{
|
|
return *h; /* handle_type is an iterator */
|
|
}
|
|
};
|
|
|
|
/* Specifier for verbose_factory_class. The simplest way to tag
|
|
* this struct as a factory specifier, so that flyweight<> accepts it
|
|
* as such, is by deriving from boost::flyweights::factory_marker.
|
|
* See the documentation for info on alternative tagging methods.
|
|
*/
|
|
|
|
struct verbose_factory: factory_marker
|
|
{
|
|
template<typename Entry,typename Key>
|
|
struct apply
|
|
{
|
|
typedef verbose_factory_class<Entry,Key> type;
|
|
} ;
|
|
};
|
|
|
|
/* ready to use it */
|
|
|
|
typedef flyweight<std::string,verbose_factory> fw_string;
|
|
|
|
int main()
|
|
{
|
|
typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
|
|
|
|
|
|
std::string text=
|
|
"I celebrate myself, and sing myself, "
|
|
"And what I assume you shall assume, "
|
|
"For every atom belonging to me as good belongs to you. "
|
|
|
|
"I loafe and invite my soul, "
|
|
"I lean and loafe at my ease observing a spear of summer grass. "
|
|
|
|
"My tongue, every atom of my blood, form'd from this soil, this air, "
|
|
"Born here of parents born here from parents the same, and their "
|
|
" parents the same, "
|
|
"I, now thirty-seven years old in perfect health begin, "
|
|
"Hoping to cease not till death.";
|
|
|
|
std::vector<fw_string> v;
|
|
|
|
text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
|
|
for(text_tokenizer::iterator it=tok.begin();it!=tok.end();){
|
|
v.push_back(fw_string(*it++));
|
|
}
|
|
|
|
return 0;
|
|
}
|