test_custom_factory.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. #include "test_custom_factory.hpp"
  11. #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
  12. #include <boost/flyweight/flyweight.hpp>
  13. #include <boost/flyweight/refcounted.hpp>
  14. #include <boost/flyweight/simple_locking.hpp>
  15. #include <boost/flyweight/static_holder.hpp>
  16. #include <boost/mpl/aux_/lambda_support.hpp>
  17. #include <list>
  18. #include "test_basic_template.hpp"
  19. using namespace boost::flyweights;
  20. /* Info on list-update containers:
  21. * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/lu_based_containers.html
  22. */
  23. template<typename Entry,typename Key>
  24. class lu_factory_class:public factory_marker
  25. {
  26. struct entry_type
  27. {
  28. entry_type(const Entry& x_):x(x_),count(0){}
  29. Entry x;
  30. std::size_t count;
  31. };
  32. typedef std::list<entry_type> container_type;
  33. public:
  34. typedef typename container_type::iterator handle_type;
  35. handle_type insert(const Entry& x)
  36. {
  37. handle_type h;
  38. for(h=cont.begin();h!=cont.end();++h){
  39. if(static_cast<const Key&>(h->x)==static_cast<const Key&>(x)){
  40. if(++(h->count)==10){
  41. h->count=0;
  42. cont.splice(cont.begin(),cont,h); /* move to front */
  43. }
  44. return h;
  45. }
  46. }
  47. cont.push_back(entry_type(x));
  48. h=cont.end();
  49. --h;
  50. return h;
  51. }
  52. void erase(handle_type h)
  53. {
  54. cont.erase(h);
  55. }
  56. const Entry& entry(handle_type h){return h->x;}
  57. private:
  58. container_type cont;
  59. public:
  60. typedef lu_factory_class type;
  61. BOOST_MPL_AUX_LAMBDA_SUPPORT(2,lu_factory_class,(Entry,Key))
  62. };
  63. struct lu_factory:factory_marker
  64. {
  65. template<typename Entry,typename Key>
  66. struct apply
  67. {
  68. typedef lu_factory_class<Entry,Key> type;
  69. };
  70. };
  71. struct custom_factory_flyweight_specifier1
  72. {
  73. template<typename T>
  74. struct apply
  75. {
  76. typedef flyweight<T,lu_factory> type;
  77. };
  78. };
  79. struct custom_factory_flyweight_specifier2
  80. {
  81. template<typename T>
  82. struct apply
  83. {
  84. typedef flyweight<
  85. T,
  86. lu_factory_class<boost::mpl::_1,boost::mpl::_2>
  87. > type;
  88. };
  89. };
  90. void test_custom_factory()
  91. {
  92. test_basic_template<custom_factory_flyweight_specifier1>();
  93. test_basic_template<custom_factory_flyweight_specifier2>();
  94. }