### Default Set Factory Configuration Example Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/configuration Shows the default configuration for `flyweight` utilizing `set_factory`. This example details how `flyweight >` translates to a configuration using `std::less` for comparison and `std::allocator` for memory management, suitable for ordered storage. ```cpp flyweight > ``` ```cpp flyweight< T, set_factory,std::allocator > > ``` -------------------------------- ### Main Function for Boost.Flyweight Serialization Example Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/serialization Provides a command-line interface to choose between saving a text file to a serialization archive or loading a serialization archive back to a text file. It includes error handling for user input and exceptions during operations. ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::flyweights; typedef flyweight fw_string; typedef std::vector text_container; void save_serialization_file() { typedef std::istreambuf_iterator char_iterator; typedef boost::tokenizer< boost::char_separator, char_iterator > tokenizer; std::cout<<"enter input text file name: "; std::string in; std::getline(std::cin,in); std::ifstream ifs(in.c_str()); if(!ifs){ std::cout<<"can't open "<( "", "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~")); text_container txt; for(tokenizer::iterator it=tok.begin();it!=tok.end();++it){ txt.push_back(fw_string(*it)); } std::cout<<"enter output serialization file name: "; std::string out; std::getline(std::cin,out); std::ofstream ofs(out.c_str()); if(!ofs){ std::cout<<"can't open "<(txt); } void load_serialization_file() { std::cout<<"enter input serialization file name: "; std::string in; std::getline(std::cin,in); std::ifstream ifs(in.c_str()); if(!ifs){ std::cout<<"can't open "<>txt; std::cout<<"enter output text file name: "; std::string out; std::getline(std::cin,out); std::ofstream ofs(out.c_str()); if(!ofs){ std::cout<<"can't open "<(ofs)); } int main() { try{ std::cout<<"1 load a text file and save it as a serialization file\n" "2 load a serialization file and save it as a text file\n"; for(;;){ std::cout<<"select option, enter to exit: "; std::string str; std::getline(std::cin,str); if(str.empty())break; std::istringstream istr(str); int option=-1; istr>>option; if(option==1)save_serialization_file(); else if(option==2)load_serialization_file(); } } catch(const std::exception& e){ std::cout<<"error: "< >` expands to a more detailed configuration involving `boost::hash`, `std::equal_to`, and `std::allocator` with `boost::mpl::_1` as a placeholder for the internal entry type. ```cpp flyweight > ``` ```cpp flyweight< T, hashed_factory< boost::hash, std::equal_to, std::allocator > > ``` -------------------------------- ### C++ Texture Flyweight with Key-Value Extraction Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/key_value Defines a 'texture' class and a 'texture_filename_extractor' to enable key-value flyweight creation. This setup allows the 'texture_flyweight' to manage 'texture' objects efficiently using their filenames as keys. The example demonstrates creating a large number of flyweights and the underlying object management. ```cpp #include #include #include #include #include #include #include using namespace boost::flyweights; /* A class simulating a texture resource loaded from file */ class texture { public: texture(const std::string& filename):filename(filename) { std::cout<<"loaded "< > texture_flyweight; int main() { /* texture filenames */ const char* texture_filenames[]={ "grass.texture","sand.texture","water.texture","wood.texture", "granite.texture","cotton.texture","concrete.texture","carpet.texture" }; const int num_texture_filenames= sizeof(texture_filenames)/sizeof(texture_filenames[0]); /* create a massive vector of textures */ std::cout<<"creating flyweights...\n"< textures; for(int i=0;i<50000;++i){ textures.push_back( texture_flyweight(texture_filenames[std::rand()%num_texture_filenames])); } /* Just for the sake of making use of the key extractor, * assign some flyweights with texture objects rather than strings. */ for(int j=0;j<50000;++j){ textures.push_back( texture_flyweight( textures[std::rand()%textures.size()].get())); } std::cout<<"\n"< Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/basic Demonstrates three methods to access flyweight data: using get() method to retrieve const reference, using smart-pointer syntax with operator->, and using implicit conversion to std::string. Shows building a full name by combining first and last name flyweights. ```C++ std::string full_name(const user_entry& user) { std::string full; full.reserve( user.first_name.get().size()+ /* using get() */ user.last_name->size()+1); /* using operator-> */ full+=user.first_name; full+=" "; full+=user.last_name; return full; } ``` -------------------------------- ### Main Entry Point with User Input Handling in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/composite Demonstrates the complete workflow by reading user input, parsing it as a lisp-like list, and pretty-printing the result. Includes exception handling to gracefully report parsing errors such as mismatched parentheses. ```cpp int main() { std::cout<<"enter list: "; std::string str; std::getline(std::cin,str); try{ pretty_print(parse_list(str)); } catch(const std::exception& e){ std::cout<<"error: "<, typename Allocator=std::allocator > class ultrafast_set { // ... }; typedef flyweight< std::string, assoc_container_factory< // MPL lambda expression follows **ultrafast_set >** > > flyweight_string; typedef flyweight< std::string, assoc_container_factory< **ultrafast_set< mpl::_1, std::less, std::allocator > >** > flyweight_string_explicit_alloc; ``` -------------------------------- ### Main program with flyweight configuration Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/parallel Entry point that reads a file, performs tokenization benchmarks comparing std::string against regular and concurrent flyweight types. Tests single-threaded and 8-threaded configurations to demonstrate performance differences. ```cpp int main(int argc, char** argv) { using namespace boost::flyweights; using regular_flyweight=flyweight; using concurrent_flyweight=flyweight< std::string, concurrent_factory<>, no_locking, no_tracking >; if(argc<2){ std::cout<<"specify a file\n"; std::exit(EXIT_FAILURE); } std::ifstream is(argv[1]); if(!is) { std::cout<<"can't open "<(is),std::istreambuf_iterator{}); parse(in,"std::string",1); parse(in,"std::string",8); parse(in,"regular flyweight",1); parse(in,"regular flyweight",8); parse(in,"concurrent flyweight",1); parse(in,"concurrent flyweight",8); } ``` -------------------------------- ### Main Function for Test Execution Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf The main function orchestrates the execution of different test cases. It prompts the user to select a test, reads a file name, and runs the chosen test, handling potential exceptions. ```C++ int main() { try{ for(int i=0;i>option; if(option>=1&&option<=num_test_cases){ --option; /* pass from 1-based menu to 0-based test_table */ break; } } std::cout<<"enter file name: "; std::string file; std::getline(std::cin,file); std::size_t result=0; result=test_table[option].test(file); } catch(const std::exception& e){ std::cout<<"error: "< > ``` ```cpp flyweight< T, concurrent_factory< boost::hash, std::equal_to, std::allocator > > ``` -------------------------------- ### Define Class Template 'foo' Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/lambda_expressions An example of an arbitrary class template 'foo' that accepts two template arguments. This serves as a basis for demonstrating lambda expression functionalities. ```cpp template class foo { // ... }; ``` -------------------------------- ### Memory Usage Reporting Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf This snippet reports the memory usage, distinguishing between flyweight and value storage. It calculates and prints the total bytes used and breaks it down if flyweight optimization is active. ```C++ std::cout<<"bytes used: "<::value){ std::size_t flyweight_mem=(txt.capacity()+txt2.capacity())*sizeof(String); std::cout<<"= flyweights("<"; } ``` -------------------------------- ### C++ Thread Pool with Explicit Flyweight Initialization Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/technical Shows a corrected C++ thread pool example where `flyweight::init()` is explicitly called to ensure static data initialization before threads are launched. This addresses the potential concurrency issue in the previous example. ```cpp class thread_pool { public: thread_pool() { **flyweight::init();** for(int i=0;i<100;++i)p[i]=shared_ptr(new thread(thread_fun)); } ... } ``` -------------------------------- ### String Equality Comparison and Timing Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf This section measures the time taken for performing equality comparisons on strings. It iterates through the string and counts character occurrences, using a timer to track performance. ```C++ t.restart(); std::size_t c=0; for(int i=0;i<100;++i){ c+=std::count(txt.begin(),txt.end(),txt[c%txt.size()]); } t.time("equality comparison time"); ``` -------------------------------- ### Character matching function for alphabetic sequences Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/parallel Inline helper function that checks if a character is alphabetic (a-z or A-Z). Used by the tokenizer to identify word boundaries in text. ```cpp inline bool match(char ch) { return (ch>='a' && ch<='z') || (ch>='A' && ch<='Z'); } ``` -------------------------------- ### String Value Access and Timing Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf This code measures the time required to access and accumulate values from strings. It uses `std::accumulate` within a loop and records the duration. ```C++ t.restart(); std::size_t s=0; for(int i=0;i<20;++i){ s+=std::accumulate(txt2.begin(),txt2.end(),s,length_adder()); } t.time("value access time"); ``` -------------------------------- ### Test Case Structure Definition Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf Defines a structure for test cases, holding a test name and a pointer to a test function. This allows for a table-driven approach to testing different string implementations. ```C++ struct test_case { const char* name; std::size_t (*test)(const std::string&); }; test_case test_table[]= { { "simple string", test::run }, { "flyweight, hashed factory", test >::run }, { "flyweight, hashed factory, no tracking", test >::run }, { "flyweight, set-based factory", test >::run }, { "flyweight, set-based factory, no tracking", test >::run } }; const int num_test_cases=sizeof(test_table)/sizeof(test_case); ``` -------------------------------- ### Save Text File to Serialization Archive with Boost.Flyweight Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/serialization Reads a text file, tokenizes its content using Boost.Tokenizer, stores tokens as Boost.Flyweight, and serializes the collection to a file using Boost.Archive. This function handles file input/output and error checking. ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::flyweights; typedef flyweight fw_string; typedef std::vector text_container; void save_serialization_file() { typedef std::istreambuf_iterator char_iterator; typedef boost::tokenizer< boost::char_separator, char_iterator > tokenizer; std::cout<<"enter input text file name: "; std::string in; std::getline(std::cin,in); std::ifstream ifs(in.c_str()); if(!ifs){ std::cout<<"can't open "<( "", "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~")); text_container txt; for(tokenizer::iterator it=tok.begin();it!=tok.end();++it){ txt.push_back(fw_string(*it)); } std::cout<<"enter output serialization file name: "; std::string out; std::getline(std::cin,out); std::ofstream ofs(out.c_str()); if(!ofs){ std::cout<<"can't open "<(txt); } ``` -------------------------------- ### Load Serialization Archive to Text File with Boost.Flyweight Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/serialization Loads a serialized Boost.Flyweight collection from a file using Boost.Archive and writes the deserialized content to a text file. This function handles file input/output and error checking, effectively converting the archive back into readable text. ```cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace boost::flyweights; typedef flyweight fw_string; typedef std::vector text_container; void load_serialization_file() { std::cout<<"enter input serialization file name: "; std::string in; std::getline(std::cin,in); std::ifstream ifs(in.c_str()); if(!ifs){ std::cout<<"can't open "<>txt; std::cout<<"enter output text file name: "; std::string out; std::getline(std::cin,out); std::ofstream ofs(out.c_str()); if(!ofs){ std::cout<<"can't open "<(ofs)); } ``` -------------------------------- ### Implement stream I/O operators for user_entry with flyweights Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/basic Implements operator<< to output user_entry data by forwarding to std::string's overload, and operator>> to input user data. Both operators work transparently with flyweight fields due to implicit conversion support. ```C++ std::ostream& operator<<(std::ostream& os,const user_entry& user) { return os<>(std::istream& is,user_entry& user) { return is>>user.first_name>>user.last_name>>user.age; } ``` -------------------------------- ### Implement user_entry constructors for flyweight initialization Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/basic Implements three constructors for user_entry: default constructor, parameterized constructor accepting C-style strings and age, and copy constructor. Demonstrates that flyweight is constructible from const char* similar to std::string and that copy operations do not throw exceptions. ```C++ user_entry::user_entry() {} user_entry::user_entry(const char* f,const char* l,int a): first_name(f), last_name(l), age(a) {} user_entry::user_entry(const user_entry& x): first_name(x.first_name), last_name(x.last_name), age(x.age) {} ``` -------------------------------- ### Produce HTML from Contextualized Characters (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/html Generates HTML output by iterating through a sequence of contextualized characters. It manages context changes using 'change_context' and emits characters to the output iterator. This function is templated for flexible input and output iterators. It depends on 'html_context', 'character', and 'change_context'. ```cpp template void produce_html(ForwardIterator first,ForwardIterator last,OutputIterator out) { html_context context; while(first!=last){ if(first->get().context!=context){ change_context(context,first->get().context,out); context=first->get().context; } *out++=(first++)->get().code; } change_context(context,html_context(),out); } ``` -------------------------------- ### C++: Define HTML Tag Data Structure for Flyweight Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/html Defines the `html_tag_data` structure to hold the name and properties of an HTML tag. Equality and hash functions are provided for use with Boost.Flyweight and Boost.Hash. ```cpp struct html_tag_data { std::string name; std::string properties; }; bool operator==(const html_tag_data& x,const html_tag_data& y) { return x.name==y.name&&x.properties==y.properties; } #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) namespace boost{ #endif std::size_t hash_value(const html_tag_data& x) { std::size_t res=0; boost::hash_combine(res,x.name); boost::hash_combine(res,x.properties); return res; } #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) } /* namespace boost */ #endif typedef flyweight html_tag; ``` -------------------------------- ### Performance Timer Utility Class in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf Simple timer class using std::clock() for measuring elapsed time in seconds. Provides restart() method to reset timer and time() method to output elapsed time with label. Used for benchmarking initialization and assignment operations. ```C++ class timer { public: timer(){restart();} void restart(){t=std::clock();} void time(const char* str) { std::cout< { list_pretty_printer():nest(0){} void operator()(const std::string& str) { indent(); std::cout<& elmsw) { indent(); std::cout<<"(\n"; ++nest; const list_elems& elms=elmsw.get(); for(list_elems::const_iterator it=elms.begin(),it_end=elms.end(); it!=it_end;++it){ boost::apply_visitor(*this,it->get()); } --nest; indent(); std::cout<<")\n"; } private: void indent()const { for(int i=nest;i--;)std::cout<<" "; } int nest; }; void pretty_print(const list& l) { list_pretty_printer pp; boost::apply_visitor(pp,l.get()); } ``` -------------------------------- ### Generic tokenizer template for forward iterators Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/parallel Template function that tokenizes a sequence of characters into words of alphabetic characters using forward iterators. Takes a callback function to process each token (begin and end iterators). Uses goto-based state machine for efficient token extraction. ```cpp template void tokenize(ForwardIterator first,ForwardIterator last,F f) { goto start; for(;;) { for(;;){ ++first; start: if(first==last)return; if(match(*first))break; } auto begin_word=first; for(;;){ if(++first==last||!match(*first)){ f(begin_word,first); if(first==last)return; else break; } } } } ``` -------------------------------- ### MPL Placeholder Expression with Argument Transformation Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/lambda_expressions Demonstrates argument transformation using MPL Placeholder Expressions. This example utilizes placeholders and standard library components like std::shared_ptr and std::less to construct the 'foo' type. ```cpp typedef foo< boost::shared_ptr, std::less > foo_specifier; ``` -------------------------------- ### Implement Flyweight-based Memoization for Fibonacci Sequence Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/examples This example demonstrates how to use Boost.Flyweight with a key-value pair and a custom compute function to implement memoization for calculating Fibonacci numbers. The `no_tracking` policy ensures memoized results persist. It takes an integer `n` and returns the nth Fibonacci number. ```cpp typedef flyweight,no_tracking> fibonacci; struct compute_fibonacci { compute_fibonacci(int n): result(n==0?0:n==1?1:fibonacci(n-2).get()+fibonacci(n-1).get()) {} operator int()const{return result;} int result; }; ``` -------------------------------- ### Access flyweight values and implicit conversions in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/basics Shows multiple ways to access flyweight values: implicit conversion to const T&, explicit get() member function, and smart-pointer syntax (operator->). Demonstrates that flyweight is convertible to const T& for transparent usage. ```cpp std::string full_name(const user_entry& user) { std::string full; full.reserve( user.first_name.get().size()+ // get() returns the underlying const std::string& user.last_name->size()+1); // flyweights also work as pointers to their // underlying value full+=user.first_name; // implicit conversion is used here full+=" "; full+=user.last_name; return full; } ``` -------------------------------- ### Custom Memory Tracking Allocator in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf Implements a custom allocator template that tracks total memory allocation and deallocation. Provides standard allocator interface with rebind support for use with STL containers. Includes specialization for void type and maintains global counter of allocated memory. ```C++ std::size_t count_allocator_mem=0; template class count_allocator { public: typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T value_type; templatestruct rebind{typedef count_allocator other;}; count_allocator(){} count_allocator(const count_allocator{}){} templatecount_allocator(const count_allocator&,int=0){} pointer address(reference x)const{return &x;} const_pointer address(const_reference x)const{return &x;} pointer allocate(size_type n,const void* =0) { pointer p=(T*)(new char[n*sizeof(T)]); count_allocator_mem+=n*sizeof(T); return p; } void deallocate(void* p,size_type n) { count_allocator_mem-=n*sizeof(T); delete [](char *)p; } size_type max_size() const{return (size_type )(-1);} void construct(pointer p,const T& val){new(p)T(val);} void destroy(pointer p){p->~T();} friend bool operator==(const count_allocator&,const count_allocator&) { return true; } friend bool operator!=(const count_allocator&,const count_allocator&) { return false; } }; ``` -------------------------------- ### Define user_entry struct with flyweight strings in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/basic Defines a user_entry structure that uses flyweight for first_name and last_name fields to optimize memory usage when storing redundant name data. The struct includes default, parameterized, and copy constructors to handle flyweight object initialization and copying. ```C++ 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 Type Detection Template Metaprogram in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf Template metaprogram that detects whether a type is a Boost.Flyweight instantiation. Uses specialization pattern to distinguish flyweight types from regular types, inheriting from boost::mpl::true_ or boost::mpl::false_ for compile-time type checking. ```C++ template struct is_flyweight: boost::mpl::false_{}; template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 > struct is_flyweight >: boost::mpl::true_{}; ``` -------------------------------- ### C++: Custom Factory for Flyweight Initialization Source: https://www.boost.org/doc/libs/latest/libs/flyweight/test/test_init Demonstrates a custom factory (`marked_hashed_factory`) designed to mark a boolean flag upon its creation. This is used to test if flyweight objects with this factory are correctly initialized during static data setup. It relies on Boost.Flyweight and Boost.Core for testing utilities. ```cpp #include "test_init.hpp" #include /* keep it first to prevent nasty warns in MSVC */ #include #include using namespace boost::flyweights; template struct marked_hashed_factory_class:hashed_factory_class { marked_hashed_factory_class(){*pmark=true;} }; template struct marked_hashed_factory:factory_marker { template struct apply { typedef marked_hashed_factory_class type; }; }; namespace boost_flyweight_test{ bool mark1=false; bool init1=flyweight >::init(); bool mark2=false; flyweight >::initializer init2; } void test_init() { BOOST_TEST(boost_flyweight_test::mark1); BOOST_TEST(boost_flyweight_test::mark2); } ``` -------------------------------- ### Compare user entries by name using flyweight equality Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/basic Implements a same_name function that compares two user_entry objects based on their first and last names using the equality operator inherited from std::string. Demonstrates that flyweight supports comparison operators with standard string semantics. ```C++ 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; } ``` -------------------------------- ### Print HTML Closing Tag (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/html A utility function to print an HTML closing tag to an output stream, excluding SGML declarations. It takes an ostream and an html_tag_data object. It checks if the tag name starts with '!' to avoid closing SGML declarations. ```cpp void print_closing_tag(std::ostream& os,const html_tag_data& x) { if(x.name[0]!='!')os<<""; } ``` -------------------------------- ### Verbose Factory Class Example for Boost.Flyweight Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/extension An example of a custom factory class that uses std::set internally and prints messages to std::cout for insert and erase operations. It demonstrates how to trace factory method calls. The handle_type is an iterator to the internal set. ```C++ template class verbose_factory_class { typedef std::set > store_type; store_type store; public: typedef typename store_type::iterator handle_type; handle_type insert(Entry&& x) { std::pair p=store.insert(std::move(x)); if(p.second){ /* new entry */ std::cout<<"new: "<<(const Key&)x< 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; } ``` -------------------------------- ### Boost.Flyweight Header Inclusion (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/configuration Shows the necessary header inclusions for using Boost.Flyweight and its default configuration components. For other components, specific headers must be explicitly included. ```cpp #include #include #include #include #include ``` -------------------------------- ### Define Concurrent Factory Flyweight Specifier 1 (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/test/test_concurrent_factory Defines a flyweight specifier that uses the default concurrent_factory. This is a basic setup for concurrent flyweight usage. ```c++ #include #include using namespace boost::flyweights; struct concurrent_factory_flyweight_specifier1 { template struct apply { typedef flyweight > type; }; }; ``` -------------------------------- ### Tokenized String Performance Test Framework in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/perf Template test framework that measures initialization and assignment performance for string types (both plain and flyweight). Reads file, tokenizes text using boost::tokenizer with custom separators, and tracks memory usage via count_allocator. Supports timing of initialization phase with restart capability. ```C++ template struct test { static std::size_t run(const std::string& file) { typedef std::vector > count_vector; typedef std::istreambuf_iterator char_iterator; typedef boost::tokenizer< boost::char_separator, char_iterator > tokenizer; std::ifstream ifs(file.c_str()); if(!ifs){ std::cout<<"can't open "<( "", "\t\n\r !\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~")); count_vector txt; for(tokenizer::iterator it=tok.begin();it!=tok.end();++it){ txt.push_back(String(it->c_str())); } t.time("initialization time"); t.restart(); count_vector txt2; } }; ``` -------------------------------- ### Main HTML Processing Pipeline (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/html The main function orchestrates the HTML processing. It reads HTML from standard input, parses it into contextualized characters using 'scan_html', optionally manipulates the character vector (e.g., reversing a portion), and then produces the resulting HTML to standard output using 'produce_html'. Dependencies include standard C++ I/O, file streams, iterators, vector, algorithm, and the custom HTML processing functions. ```cpp int main() { std::cout<<"input html file: "; std::string in; std::getline(std::cin,in); std::ifstream ifs(in.c_str()); if(!ifs){ std::cout<<"can't open "< istrbuf_iterator; std::vector html_source; std::copy( istrbuf_iterator(ifs),istrbuf_iterator(), std::back_inserter(html_source)); std::vector scanned_html; scan_html( html_source.begin(),html_source.end(),std::back_inserter(scanned_html)); std::reverse( scanned_html.begin()+scanned_html.size()/4, scanned_html.begin()+3*(scanned_html.size()/4)); std::cout<<"output html file: "; std::string out; std::getline(std::cin,out); std::ofstream ofs(out.c_str()); if(!ofs){ std::cout<<"can't open "< ostrbuf_iterator; produce_html(scanned_html.begin(),scanned_html.end(),ostrbuf_iterator(ofs)); return 0; } ``` -------------------------------- ### Flyweight Get Key Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/reference/flyweight Retrieves the key associated with the flyweight object. The key is used to construct or identify the underlying value. The exception guarantee depends on the Key Extractor and whether the flyweight is key-value. ```C++ const key_type& get_key() const noexcept; ``` -------------------------------- ### Construct and use flyweight objects in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/basics Demonstrates constructor initialization of flyweight members and relational operator usage. Flyweight objects behave like T objects, supporting multi-argument constructors and standard comparison operators for seamless integration. ```cpp // flyweight can be constructed in the same way as T objects can, // even with multiple argument constructors user_entry::user_entry(const char* f,const char* l,int a,...): first_name(f), last_name(l), age(a), ... {} // flyweight classes have relational operators replicating the // semantics of the underyling type bool same_name(const user_entry& user1,const user_entry& user2) { return user1.first_name==user2.first_name && user1.last_name==user2.last_name; } ``` -------------------------------- ### Flyweight Get Value Access Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/reference/flyweight Provides access to the underlying value associated with the flyweight object. Supports const reference and pointer access, as well as conversion to a const reference. These operations are typically noexcept. ```C++ const value_type& get() const noexcept; const value_type& operator*() const noexcept; operator const value_type&() const noexcept; const value_type* operator->() const noexcept; ``` -------------------------------- ### Parse Lisp-Like List Syntax in C++ Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/composite Implements recursive list parser that tokenizes input strings and constructs nested list structures. Handles parentheses nesting, validates matching pairs, and builds flyweight-wrapped list objects. Uses Boost.tokenizer for string tokenization and includes error handling for malformed input. ```cpp template list parse_list(InputIterator& first,InputIterator last,int nest) { list_elems elms; while(first!=last){ std::string str=*first++; if(str=="("){ elms.push_back(parse_list(first,last,nest+1)); } else if(str==")"){ if(nest==0)throw std::runtime_error("unmatched )"); return list(elms); } else{ elms.push_back(list(str)); } } if(nest!=0)throw std::runtime_error("unmatched ("); return list(elms); } list parse_list(const std::string str) { typedef boost::tokenizer > tokenizer; tokenizer tok(str,boost::char_separator(" ","()")); tokenizer::iterator begin=tok.begin(); return parse_list(begin,tok.end(),0); } ``` -------------------------------- ### Define user_entry struct with flyweight optimization Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/basics Optimized struct definition that replaces std::string members with flyweight to automatically deduplicate repeated names across millions of instances. Requires #include . ```cpp #include struct user_entry { flyweight first_name; flyweight last_name; int age; ... }; ``` -------------------------------- ### Example Instantiation of assoc_container_factory_class (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/reference/factories Illustrates how `assoc_container_factory_class` can be instantiated with `std::set`. This specific instantiation creates a factory for `derived` elements, implicitly associated with the `base` type, assuming `derived` inherits from `base`. ```cpp assoc_container_factory_class< std::set > // derived inherits from base > ``` -------------------------------- ### Parse HTML Tags and Manage Context (C++) Source: https://www.boost.org/doc/libs/latest/libs/flyweight/example/html Parses HTML content, identifying opening and closing tags to manage a context stack. It processes characters one by one, updating the HTML context and outputting characters accordingly. Dependencies include custom types like 'parse_tag_res', 'html_context_data', 'html_tag_data', and 'character'. ```cpp if(*first=='<'){ ++first; parse_tag_res res=parse_tag(first,last); if(res.type==opening){ context.push_back(res.tag); continue; } else if(res.type==closing){ for(html_context_data::reverse_iterator rit=context.rbegin(); rit!=context.rend();++rit){ if(rit->get().name==res.tag->name){ context.erase(rit.base()-1,context.end()); break; } } continue; } } *out++=character(*first++,html_context(context)); ``` -------------------------------- ### MPL Metafunction Class with Reduced Arity Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/tutorial/lambda_expressions Example of an MPL Metafunction Class accepting fewer arguments than the target class template. This specifier uses only the first argument and a default for the second. ```cpp struct foo_specifier { template struct apply { typedef foo > type; }; }; ``` -------------------------------- ### Include Boost.Flyweight convenience header with default components Source: https://www.boost.org/doc/libs/latest/libs/flyweight/doc/reference/index This is the primary convenience header that includes the main flyweight class template along with default components: hashed factory, reference counting, simple locking, and static holder. Use this header for typical Flyweight pattern implementations without custom configuration. ```cpp #include #include #include #include #include ```