123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /* 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;
- }
|