basic.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /* Boost.Flyweight basic example.
  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 <boost/bind.hpp>
  11. #include <boost/flyweight.hpp>
  12. #include <algorithm>
  13. #include <iostream>
  14. #include <iterator>
  15. #include <sstream>
  16. #include <string>
  17. #include <vector>
  18. using namespace boost::flyweights;
  19. /* Information associated to a given user of some massive system.
  20. * first_name and last_name are turned into flyweights to leverage the
  21. * implicit redundancy of names within the user community.
  22. */
  23. struct user_entry
  24. {
  25. flyweight<std::string> first_name;
  26. flyweight<std::string> last_name;
  27. int age;
  28. user_entry();
  29. user_entry(const char* first_name,const char* last_name,int age);
  30. user_entry(const user_entry& x);
  31. };
  32. /* flyweight<std::string> default ctor simply calls the default ctor of
  33. * std::string.
  34. */
  35. user_entry::user_entry()
  36. {}
  37. /* flyweight<std::string> is constructible from a const char* much as
  38. * a std::string is.
  39. */
  40. user_entry::user_entry(const char* f,const char* l,int a):
  41. first_name(f),
  42. last_name(l),
  43. age(a)
  44. {}
  45. /* flyweight's are copyable and assignable --unlike std::string,
  46. * copy and assignment of flyweight<std::string>s do not ever throw.
  47. */
  48. user_entry::user_entry(const user_entry& x):
  49. first_name(x.first_name),
  50. last_name(x.last_name),
  51. age(x.age)
  52. {}
  53. /* flyweight<std::string> has operator==,!=,<,>,<=,>= with the same
  54. * semantics as those of std::string.
  55. */
  56. bool same_name(const user_entry& user1,const user_entry& user2)
  57. {
  58. bool b=user1.first_name==user2.first_name &&
  59. user1.last_name==user2.last_name;
  60. return b;
  61. }
  62. /* operator<< forwards to the std::string overload */
  63. std::ostream& operator<<(std::ostream& os,const user_entry& user)
  64. {
  65. return os<<user.first_name<<" "<<user.last_name<<" "<<user.age;
  66. }
  67. /* operator>> internally uses std::string's operator>> */
  68. std::istream& operator>>(std::istream& is,user_entry& user)
  69. {
  70. return is>>user.first_name>>user.last_name>>user.age;
  71. }
  72. std::string full_name(const user_entry& user)
  73. {
  74. std::string full;
  75. /* get() returns the underlying const std::string& */
  76. full.reserve(
  77. user.first_name.get().size()+user.last_name.get().size()+1);
  78. /* here, on the other hand, implicit conversion is used */
  79. full+=user.first_name;
  80. full+=" ";
  81. full+=user.last_name;
  82. return full;
  83. }
  84. /* flyweight<std::string> value is immutable, but a flyweight object can
  85. * be assigned a different value.
  86. */
  87. void change_name(user_entry& user,const std::string& f,const std::string& l)
  88. {
  89. user.first_name=f;
  90. user.last_name=l;
  91. }
  92. int main()
  93. {
  94. /* play a little with a vector of user_entry's */
  95. std::string users_txt=
  96. "olegh smith 31\n"
  97. "john brown 28\n"
  98. "anna jones 45\n"
  99. "maria garcia 30\n"
  100. "john fox 56\n"
  101. "anna brown 19\n"
  102. "thomas smith 46\n"
  103. "andrew martin 28";
  104. std::vector<user_entry> users;
  105. std::istringstream iss(users_txt);
  106. while(iss){
  107. user_entry u;
  108. if(iss>>u)users.push_back(u);
  109. }
  110. change_name(users[0],"oleg","smith");
  111. user_entry anna("anna","jones",20);
  112. std::replace_if(
  113. users.begin(),users.end(),
  114. boost::bind(same_name,_1,anna),
  115. anna);
  116. std::copy(
  117. users.begin(),users.end(),
  118. std::ostream_iterator<user_entry>(std::cout,"\n"));
  119. return 0;
  120. }