custom_factory.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* Boost.Flyweight example of 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. /* We include the default components of Boost.Flyweight except the factory,
  11. * which will be provided by ourselves.
  12. */
  13. #include <boost/flyweight/flyweight.hpp>
  14. #include <boost/flyweight/factory_tag.hpp>
  15. #include <boost/flyweight/static_holder.hpp>
  16. #include <boost/flyweight/simple_locking.hpp>
  17. #include <boost/flyweight/refcounted.hpp>
  18. #include <boost/tokenizer.hpp>
  19. #include <functional>
  20. #include <iostream>
  21. #include <set>
  22. using namespace boost::flyweights;
  23. /* custom factory based on std::set with some logging capabilities */
  24. /* Entry is the type of the stored objects. Value is the type
  25. * on which flyweight operates, that is, the T in flyweoght<T>. It
  26. * is guaranteed that Entry implicitly converts to const Value&.
  27. * The factory class could accept other template arguments (for
  28. * instance, a comparison predicate for the values), we leave it like
  29. * that for simplicity.
  30. */
  31. template<typename Entry,typename Key>
  32. class verbose_factory_class
  33. {
  34. /* Entry store. Since Entry is implicitly convertible to const Key&,
  35. * we can directly use std::less<Key> as the comparer for std::set.
  36. */
  37. typedef std::set<Entry,std::less<Key> > store_type;
  38. store_type store;
  39. public:
  40. typedef typename store_type::iterator handle_type;
  41. handle_type insert(const Entry& x)
  42. {
  43. /* locate equivalent entry or insert otherwise */
  44. std::pair<handle_type, bool> p=store.insert(x);
  45. if(p.second){ /* new entry */
  46. std::cout<<"new: "<<(const Key&)x<<std::endl;
  47. }
  48. else{ /* existing entry */
  49. std::cout<<"hit: "<<(const Key&)x<<std::endl;
  50. }
  51. return p.first;
  52. }
  53. void erase(handle_type h)
  54. {
  55. std::cout<<"del: "<<(const Key&)*h<<std::endl;
  56. store.erase(h);
  57. }
  58. const Entry& entry(handle_type h)
  59. {
  60. return *h; /* handle_type is an iterator */
  61. }
  62. };
  63. /* Specifier for verbose_factory_class. The simplest way to tag
  64. * this struct as a factory specifier, so that flyweight<> accepts it
  65. * as such, is by deriving from boost::flyweights::factory_marker.
  66. * See the documentation for info on alternative tagging methods.
  67. */
  68. struct verbose_factory: factory_marker
  69. {
  70. template<typename Entry,typename Key>
  71. struct apply
  72. {
  73. typedef verbose_factory_class<Entry,Key> type;
  74. } ;
  75. };
  76. /* ready to use it */
  77. typedef flyweight<std::string,verbose_factory> fw_string;
  78. int main()
  79. {
  80. typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
  81. std::string text=
  82. "I celebrate myself, and sing myself, "
  83. "And what I assume you shall assume, "
  84. "For every atom belonging to me as good belongs to you. "
  85. "I loafe and invite my soul, "
  86. "I lean and loafe at my ease observing a spear of summer grass. "
  87. "My tongue, every atom of my blood, form'd from this soil, this air, "
  88. "Born here of parents born here from parents the same, and their "
  89. " parents the same, "
  90. "I, now thirty-seven years old in perfect health begin, "
  91. "Hoping to cease not till death.";
  92. std::vector<fw_string> v;
  93. text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
  94. for(text_tokenizer::iterator it=tok.begin();it!=tok.end();){
  95. v.push_back(fw_string(*it++));
  96. }
  97. return 0;
  98. }