libs/flyweight/example/basic.cpp
/* Boost.Flyweight basic example.
*
* Copyright 2006-2020 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 <boost/bind/bind.hpp>
#include <boost/flyweight.hpp>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
using namespace boost::flyweights;
using namespace boost::placeholders;
/* 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<std::string> first_name;
flyweight<std::string> 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<std::string> default ctor simply calls the default ctor of
* std::string.
*/
user_entry::user_entry()
{}
/* flyweight<std::string> 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 flyweight<std::string>s 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<std::string> 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<<user.first_name<<" "<<user.last_name<<" "<<user.age;
}
/* operator>> 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<std::string> 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<user_entry> 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<user_entry>(std::cout,"\n"));
return 0;
}