/* Boost.Flyweight basic example. * * 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. */ #include #include #include #include #include #include #include #include using namespace boost::flyweights; /* Information associated to a given user of some massive system. * first_name and last_name are turned into flyweights to leverage the * implicit redundancy of names within the user community. */ struct user_entry { flyweight first_name; flyweight last_name; int age; user_entry(); user_entry(const char* first_name,const char* last_name,int age); user_entry(const user_entry& x); }; /* flyweight default ctor simply calls the default ctor of * std::string. */ user_entry::user_entry() {} /* flyweight is constructible from a const char* much as * a std::string is. */ user_entry::user_entry(const char* f,const char* l,int a): first_name(f), last_name(l), age(a) {} /* flyweight's are copyable and assignable --unlike std::string, * copy and assignment of flyweights do not ever throw. */ user_entry::user_entry(const user_entry& x): first_name(x.first_name), last_name(x.last_name), age(x.age) {} /* flyweight has operator==,!=,<,>,<=,>= with the same * semantics as those of std::string. */ bool same_name(const user_entry& user1,const user_entry& user2) { bool b=user1.first_name==user2.first_name && user1.last_name==user2.last_name; return b; } /* operator<< forwards to the std::string overload */ std::ostream& operator<<(std::ostream& os,const user_entry& user) { return os<> internally uses std::string's operator>> */ std::istream& operator>>(std::istream& is,user_entry& user) { return is>>user.first_name>>user.last_name>>user.age; } std::string full_name(const user_entry& user) { std::string full; /* get() returns the underlying const std::string& */ full.reserve( user.first_name.get().size()+user.last_name.get().size()+1); /* here, on the other hand, implicit conversion is used */ full+=user.first_name; full+=" "; full+=user.last_name; return full; } /* flyweight value is immutable, but a flyweight object can * be assigned a different value. */ void change_name(user_entry& user,const std::string& f,const std::string& l) { user.first_name=f; user.last_name=l; } int main() { /* play a little with a vector of user_entry's */ std::string users_txt= "olegh smith 31\n" "john brown 28\n" "anna jones 45\n" "maria garcia 30\n" "john fox 56\n" "anna brown 19\n" "thomas smith 46\n" "andrew martin 28"; std::vector users; std::istringstream iss(users_txt); while(iss){ user_entry u; if(iss>>u)users.push_back(u); } change_name(users[0],"oleg","smith"); user_entry anna("anna","jones",20); std::replace_if( users.begin(),users.end(), boost::bind(same_name,_1,anna), anna); std::copy( users.begin(),users.end(), std::ostream_iterator(std::cout,"\n")); return 0; }