summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/flyweight
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/boost/libs/flyweight
parentInitial commit. (diff)
downloadceph-b26c4052f3542036551aa9dec9caa4226e456195.tar.xz
ceph-b26c4052f3542036551aa9dec9caa4226e456195.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/flyweight')
-rw-r--r--src/boost/libs/flyweight/CMakeLists.txt38
-rw-r--r--src/boost/libs/flyweight/example/Jamfile.v255
-rw-r--r--src/boost/libs/flyweight/example/basic.cpp153
-rw-r--r--src/boost/libs/flyweight/example/composite.cpp174
-rw-r--r--src/boost/libs/flyweight/example/custom_factory.cpp122
-rw-r--r--src/boost/libs/flyweight/example/fibonacci.cpp58
-rw-r--r--src/boost/libs/flyweight/example/html.cpp321
-rw-r--r--src/boost/libs/flyweight/example/key_value.cpp99
-rw-r--r--src/boost/libs/flyweight/example/perf.cpp312
-rw-r--r--src/boost/libs/flyweight/example/serialization.cpp133
-rw-r--r--src/boost/libs/flyweight/index.html20
-rw-r--r--src/boost/libs/flyweight/meta/libraries.json15
-rw-r--r--src/boost/libs/flyweight/test/Jamfile.v236
-rw-r--r--src/boost/libs/flyweight/test/heavy_objects.hpp106
-rw-r--r--src/boost/libs/flyweight/test/intermod_holder_dll.cpp17
-rw-r--r--src/boost/libs/flyweight/test/intermod_holder_dll.hpp41
-rw-r--r--src/boost/libs/flyweight/test/test_all_main.cpp38
-rw-r--r--src/boost/libs/flyweight/test/test_assoc_cont_fact_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_assoc_cont_factory.cpp91
-rw-r--r--src/boost/libs/flyweight/test/test_assoc_cont_factory.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_basic.cpp68
-rw-r--r--src/boost/libs/flyweight/test/test_basic.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_basic_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_basic_template.hpp304
-rw-r--r--src/boost/libs/flyweight/test/test_custom_factory.cpp111
-rw-r--r--src/boost/libs/flyweight/test/test_custom_factory.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_custom_factory_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_init.cpp49
-rw-r--r--src/boost/libs/flyweight/test/test_init.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_init_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_intermod_holder.cpp34
-rw-r--r--src/boost/libs/flyweight/test/test_intermod_holder.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_intermod_holder_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_multictor.cpp191
-rw-r--r--src/boost/libs/flyweight/test/test_multictor.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_multictor_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_no_locking.cpp35
-rw-r--r--src/boost/libs/flyweight/test/test_no_locking.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_no_locking_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_no_tracking.cpp35
-rw-r--r--src/boost/libs/flyweight/test/test_no_tracking.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_no_tracking_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_serialization.cpp31
-rw-r--r--src/boost/libs/flyweight/test/test_serialization.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_serialization_main.cpp18
-rw-r--r--src/boost/libs/flyweight/test/test_serialization_template.hpp128
-rw-r--r--src/boost/libs/flyweight/test/test_set_factory.cpp72
-rw-r--r--src/boost/libs/flyweight/test/test_set_factory.hpp11
-rw-r--r--src/boost/libs/flyweight/test/test_set_factory_main.cpp18
49 files changed, 3177 insertions, 0 deletions
diff --git a/src/boost/libs/flyweight/CMakeLists.txt b/src/boost/libs/flyweight/CMakeLists.txt
new file mode 100644
index 000000000..55f69cf17
--- /dev/null
+++ b/src/boost/libs/flyweight/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Generated by `boostdep --cmake flyweight`
+# Copyright 2020 Peter Dimov
+# Distributed under the Boost Software License, Version 1.0.
+# https://www.boost.org/LICENSE_1_0.txt
+
+cmake_minimum_required(VERSION 3.5...3.16)
+
+project(boost_flyweight VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
+
+add_library(boost_flyweight INTERFACE)
+add_library(Boost::flyweight ALIAS boost_flyweight)
+
+target_include_directories(boost_flyweight INTERFACE include)
+
+target_link_libraries(boost_flyweight
+ INTERFACE
+ Boost::assert
+ Boost::config
+ Boost::container_hash
+ Boost::core
+ Boost::detail
+ Boost::interprocess
+ Boost::mpl
+ Boost::multi_index
+ Boost::parameter
+ Boost::preprocessor
+ Boost::serialization
+ Boost::smart_ptr
+ Boost::throw_exception
+ Boost::type_traits
+)
+
+if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
+
+ add_subdirectory(test)
+
+endif()
+
diff --git a/src/boost/libs/flyweight/example/Jamfile.v2 b/src/boost/libs/flyweight/example/Jamfile.v2
new file mode 100644
index 000000000..8a7506625
--- /dev/null
+++ b/src/boost/libs/flyweight/example/Jamfile.v2
@@ -0,0 +1,55 @@
+# Boost.Flyweight examples Jamfile
+#
+# Copyright 2006-2014 Joaquín M López Muñoz.
+# 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.
+
+project
+ : requirements
+ <os>LINUX:<threading>multi
+ ;
+
+exe basic
+ : basic.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe composite
+ : composite.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe custom_factory
+ : custom_factory.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe fibonacci
+ : fibonacci.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe html
+ : html.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe key_value
+ : key_value.cpp
+ : <include>$(BOOST_ROOT)
+ ;
+
+exe perf
+ : perf.cpp
+ : <include>$(BOOST_ROOT)
+ : release
+ ;
+
+exe serialization
+ : serialization.cpp
+ /boost/serialization//boost_serialization/<link>static
+ : <include>$(BOOST_ROOT)
+ ;
diff --git a/src/boost/libs/flyweight/example/basic.cpp b/src/boost/libs/flyweight/example/basic.cpp
new file mode 100644
index 000000000..286f735f2
--- /dev/null
+++ b/src/boost/libs/flyweight/example/basic.cpp
@@ -0,0 +1,153 @@
+/* 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;
+}
diff --git a/src/boost/libs/flyweight/example/composite.cpp b/src/boost/libs/flyweight/example/composite.cpp
new file mode 100644
index 000000000..1395f412d
--- /dev/null
+++ b/src/boost/libs/flyweight/example/composite.cpp
@@ -0,0 +1,174 @@
+/* Boost.Flyweight example of a composite design.
+ *
+ * Copyright 2006-2014 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/flyweight.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/variant.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/recursive_wrapper.hpp>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+using namespace boost::flyweights;
+
+/* A node of a lisp-like list can be modeled as a boost::variant of
+ * 1. A string (primitive node)
+ * 2. A vector of nodes (embedded list)
+ * To save space, 2 is stored as a vector of flyweights.
+ * As is usual with recursive data structures, a node can be thought
+ * of also as a list. To close the flyweight circle, the final
+ * type list is a flyweight wrapper, so that the final structure can
+ * be described as follows in BNF-like style:
+ *
+ * list ::= flyweight<list_impl>
+ * list_impl ::= std::string | std::vector<list>
+ */
+
+struct list_elems;
+
+typedef boost::variant<
+ std::string,
+ boost::recursive_wrapper<list_elems>
+> list_impl;
+
+struct list_elems:std::vector<flyweight<list_impl> >{};
+
+typedef flyweight<list_impl> list;
+
+/* list_impl must be hashable to be used by flyweight: If a
+ * node is a std::string, its hash resolves to that of the string;
+ * if it is a vector of flyweight nodes, we combine their corresponding
+ * hash values. As hashing a flyweight does not involve actually hashing
+ * its pointed-to value, the resulting computation does not recursively
+ * descend down the entire data structure.
+ */
+
+struct list_hasher:boost::static_visitor<std::size_t>
+{
+ std::size_t operator()(const std::string& str)const
+ {
+ boost::hash<std::string> h;
+ return h(str);
+ }
+
+ std::size_t operator()(const list_elems& elms)const
+ {
+ std::size_t res=0;
+ for(list_elems::const_iterator it=elms.begin(),it_end=elms.end();
+ it!=it_end;++it){
+ boost::hash_combine(res,*it);
+ }
+ return res;
+ }
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+std::size_t hash_value(const list_impl& limpl)
+{
+ return boost::apply_visitor(list_hasher(),limpl);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+/* basic pretty printer with indentation according to the nesting level */
+
+struct list_pretty_printer:boost::static_visitor<>
+{
+ list_pretty_printer():nest(0){}
+
+ void operator()(const std::string& str)
+ {
+ indent();
+ std::cout<<str<<"\n";
+ }
+
+ void operator()(const boost::recursive_wrapper<list_elems>& 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());
+}
+
+/* list parser */
+
+template<typename InputIterator>
+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<boost::char_separator<char> > tokenizer;
+ tokenizer tok(str,boost::char_separator<char>(" ","()"));
+ tokenizer::iterator begin=tok.begin();
+ return parse_list(begin,tok.end(),0);
+}
+
+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: "<<e.what()<<"\n";
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/custom_factory.cpp b/src/boost/libs/flyweight/example/custom_factory.cpp
new file mode 100644
index 000000000..3b9b2d889
--- /dev/null
+++ b/src/boost/libs/flyweight/example/custom_factory.cpp
@@ -0,0 +1,122 @@
+/* Boost.Flyweight example of custom factory.
+ *
+ * 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.
+ */
+
+/* We include the default components of Boost.Flyweight except the factory,
+ * which will be provided by ourselves.
+ */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/factory_tag.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/tokenizer.hpp>
+#include <functional>
+#include <iostream>
+#include <set>
+
+using namespace boost::flyweights;
+
+/* custom factory based on std::set with some logging capabilities */
+
+/* Entry is the type of the stored objects. Value is the type
+ * on which flyweight operates, that is, the T in flyweoght<T>. It
+ * is guaranteed that Entry implicitly converts to const Value&.
+ * The factory class could accept other template arguments (for
+ * instance, a comparison predicate for the values), we leave it like
+ * that for simplicity.
+ */
+
+template<typename Entry,typename Key>
+class verbose_factory_class
+{
+ /* Entry store. Since Entry is implicitly convertible to const Key&,
+ * we can directly use std::less<Key> as the comparer for std::set.
+ */
+
+ typedef std::set<Entry,std::less<Key> > store_type;
+
+ store_type store;
+
+public:
+ typedef typename store_type::iterator handle_type;
+
+ handle_type insert(const Entry& x)
+ {
+ /* locate equivalent entry or insert otherwise */
+
+ std::pair<handle_type, bool> p=store.insert(x);
+ if(p.second){ /* new entry */
+ std::cout<<"new: "<<(const Key&)x<<std::endl;
+ }
+ else{ /* existing entry */
+ std::cout<<"hit: "<<(const Key&)x<<std::endl;
+ }
+ return p.first;
+ }
+
+ void erase(handle_type h)
+ {
+ std::cout<<"del: "<<(const Key&)*h<<std::endl;
+ store.erase(h);
+ }
+
+ const Entry& entry(handle_type h)
+ {
+ return *h; /* handle_type is an iterator */
+ }
+};
+
+/* Specifier for verbose_factory_class. The simplest way to tag
+ * this struct as a factory specifier, so that flyweight<> accepts it
+ * as such, is by deriving from boost::flyweights::factory_marker.
+ * See the documentation for info on alternative tagging methods.
+ */
+
+struct verbose_factory: factory_marker
+{
+ template<typename Entry,typename Key>
+ struct apply
+ {
+ typedef verbose_factory_class<Entry,Key> type;
+ } ;
+};
+
+/* ready to use it */
+
+typedef flyweight<std::string,verbose_factory> fw_string;
+
+int main()
+{
+ typedef boost::tokenizer<boost::char_separator<char> > text_tokenizer;
+
+
+ std::string text=
+ "I celebrate myself, and sing myself, "
+ "And what I assume you shall assume, "
+ "For every atom belonging to me as good belongs to you. "
+
+ "I loafe and invite my soul, "
+ "I lean and loafe at my ease observing a spear of summer grass. "
+
+ "My tongue, every atom of my blood, form'd from this soil, this air, "
+ "Born here of parents born here from parents the same, and their "
+ " parents the same, "
+ "I, now thirty-seven years old in perfect health begin, "
+ "Hoping to cease not till death.";
+
+ std::vector<fw_string> v;
+
+ text_tokenizer tok(text,boost::char_separator<char>(" \t\n.,;:!?'\"-"));
+ for(text_tokenizer::iterator it=tok.begin();it!=tok.end();){
+ v.push_back(fw_string(*it++));
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/fibonacci.cpp b/src/boost/libs/flyweight/example/fibonacci.cpp
new file mode 100644
index 000000000..618c5f2f0
--- /dev/null
+++ b/src/boost/libs/flyweight/example/fibonacci.cpp
@@ -0,0 +1,58 @@
+/* Boost.Flyweight example of flyweight-based memoization.
+ *
+ * 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 <boost/flyweight.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <boost/flyweight/no_tracking.hpp>
+#include <boost/noncopyable.hpp>
+#include <iostream>
+
+using namespace boost::flyweights;
+
+/* Memoized calculation of Fibonacci numbers */
+
+/* This class takes an int n and calculates F(n) at construction time */
+
+struct compute_fibonacci;
+
+/* A Fibonacci number can be modeled as a key-value flyweight
+ * We choose the no_tracking policy so that the calculations
+ * persist for future use throughout the program. See
+ * Tutorial: Configuring Boost.Flyweight: Tracking policies for
+ * further information on tracking policies.
+ */
+
+typedef flyweight<key_value<int,compute_fibonacci>,no_tracking> fibonacci;
+
+/* Implementation of compute_fibonacci. Note that the construction
+ * of compute_fibonacci(n) uses fibonacci(n-1) and fibonacci(n-2),
+ * which effectively memoizes the computation.
+ */
+
+struct compute_fibonacci:private boost::noncopyable
+{
+ 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;
+};
+
+int main()
+{
+ /* list some Fibonacci numbers */
+
+ for(int n=0;n<40;++n){
+ std::cout<<"F("<<n<<")="<<fibonacci(n)<<std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/html.cpp b/src/boost/libs/flyweight/example/html.cpp
new file mode 100644
index 000000000..1fa6d34c0
--- /dev/null
+++ b/src/boost/libs/flyweight/example/html.cpp
@@ -0,0 +1,321 @@
+/* Boost.Flyweight example of flyweight-based formatted text processing.
+ *
+ * Copyright 2006-2014 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/flyweight.hpp>
+#include <boost/functional/hash.hpp>
+#include <algorithm>
+#include <cctype>
+#include <cstdio>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{using ::exit;using ::tolower;}
+#endif
+
+using namespace boost::flyweights;
+
+/* An HTML tag consists of a name and optional properties of the form
+ * name1=value1 ... namen=valuen. We do not need to parse the properties
+ * for the purposes of the program, hence they are all stored in
+ * html_tag_data::properties in raw form.
+ */
+
+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;
+}
+
+/* See the portability section of Boost.Hash at
+ * http://boost.org/doc/html/hash/portability.html
+ * for an explanation of the ADL-related workarounds.
+ */
+
+#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_data> html_tag;
+
+/* parse_tag is passed an iterator positioned at the first char of
+ * the tag after the opening '<' and returns, if succesful, a parsed tag
+ * and whether it is opening (<xx>) or closing (</xx>).
+ */
+
+enum tag_type{opening,closing,failure};
+
+struct parse_tag_res
+{
+ parse_tag_res(tag_type type_,const html_tag_data& tag_=html_tag_data()):
+ type(type_),tag(tag_){}
+ parse_tag_res(const parse_tag_res& x):type(x.type),tag(x.tag){}
+
+ tag_type type;
+ html_tag tag;
+};
+
+template<typename ForwardIterator>
+parse_tag_res parse_tag(ForwardIterator& first,ForwardIterator last)
+{
+ html_tag_data tag;
+ std::string buf;
+ bool in_quote=false;
+ for(ForwardIterator it=first;it!=last;){
+ char ch=*it++;
+ if(ch=='>'&&!in_quote){ /* ignore '>'s if inside quotes */
+ tag_type type;
+ std::string::size_type
+ bname=buf.find_first_not_of("\t\n\r "),
+ ename=bname==std::string::npos?
+ std::string::npos:
+ buf.find_first_of("\t\n\r ",bname),
+ bprop=ename==std::string::npos?
+ std::string::npos:
+ buf.find_first_not_of("\t\n\r ",ename);
+ if(bname==ename){ /* null name */
+ return parse_tag_res(failure);
+ }
+ else if(buf[bname]=='/'){ /* closing tag */
+ type=closing;
+ ++bname;
+ }
+ else type=opening;
+ tag.name=buf.substr(bname,ename-bname);
+ std::transform( /* normalize tag name to lower case */
+ tag.name.begin(),tag.name.end(),tag.name.begin(),
+ (int(*)(int))std::tolower);
+ if(bprop!=std::string::npos){
+ tag.properties=buf.substr(bprop,buf.size());
+ }
+ first=it; /* result good, consume the chars */
+ return parse_tag_res(type,tag);
+ }
+ else{
+ if(ch=='"')in_quote=!in_quote;
+ buf+=ch;
+ }
+ }
+ return parse_tag_res(failure); /* end reached and found no '>' */
+}
+
+/* A character context is just a vector containing the tags enclosing the
+ * character, from the outermost level to the innermost.
+ */
+
+typedef std::vector<html_tag> html_context_data;
+typedef flyweight<html_context_data> html_context;
+
+/* A character is a char code plus its context.
+ */
+
+struct character_data
+{
+ character_data(char code_=0,html_context context_=html_context()):
+ code(code_),context(context_){}
+ character_data(const character_data& x):code(x.code),context(x.context){}
+
+ char code;
+ html_context context;
+};
+
+bool operator==(const character_data& x,const character_data& y)
+{
+ return x.code==y.code&&x.context==y.context;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+std::size_t hash_value(const character_data& x)
+{
+ std::size_t res=0;
+ boost::hash_combine(res,x.code);
+ boost::hash_combine(res,x.context);
+ return res;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+typedef flyweight<character_data> character;
+
+/* scan_html converts HTML code into a stream of contextualized characters.
+ */
+
+template<typename ForwardIterator,typename OutputIterator>
+void scan_html(ForwardIterator first,ForwardIterator last,OutputIterator out)
+{
+ html_context_data context;
+ while(first!=last){
+ if(*first=='<'){ /* tag found */
+ ++first;
+ parse_tag_res res=parse_tag(first,last);
+ if(res.type==opening){ /* add to contex */
+ context.push_back(res.tag);
+ continue;
+ }
+ else if(res.type==closing){ /* remove from context */
+ /* Pop all tags from the innermost to the matching one; this takes
+ * care of missing </xx>s like vg. in <ul><li>hello</ul>.
+ */
+
+ for(html_context_data::reverse_iterator rit=context.rbegin();
+ rit!=context.rend();++rit){
+ if(rit->get().name==res.tag.get().name){
+ context.erase(rit.base()-1,context.end());
+ break;
+ }
+ }
+ continue;
+ }
+ }
+ *out++=character(*first++,html_context(context));
+ }
+}
+
+/* HTML-producing utilities */
+
+void print_opening_tag(std::ostream& os,const html_tag_data& x)
+{
+ os<<"<"<<x.name;
+ if(!x.properties.empty())os<<" "<<x.properties;
+ os<<">";
+}
+
+void print_closing_tag(std::ostream& os,const html_tag_data& x)
+{
+ /* SGML declarations (beginning with '!') are not closed */
+
+ if(x.name[0]!='!')os<<"</"<<x.name<<">";
+}
+
+/* change_context takes contexts from and to with tags
+ *
+ * from<- c1 ... cn fn+1 ... fm
+ * to <- c1 ... cn tn+1 ... tk
+ *
+ * (that is, they share the first n tags, n might be 0), and
+ * produces code closing fm ... fn+1 and opening tn+1 ... tk.
+ */
+
+template<typename OutputIterator>
+void change_context(
+ const html_context_data& from,const html_context_data& to,
+ OutputIterator out)
+{
+ std::ostringstream oss;
+ html_context_data::const_iterator
+ it0=from.begin(),
+ it0_end=from.end(),
+ it1=to.begin(),
+ it1_end=to.end();
+ for(;it0!=it0_end&&it1!=it1_end&&*it0==*it1;++it0,++it1);
+ while(it0_end!=it0)print_closing_tag(oss,*--it0_end);
+ while(it1!=it1_end)print_opening_tag(oss,*it1++);
+ std::string str=oss.str();
+ std::copy(str.begin(),str.end(),out);
+}
+
+/* produce_html is passed a bunch of contextualized characters and emits
+ * the corresponding HTML. The algorithm is simple: tags are opened and closed
+ * as a result of the context from one character to the following changing.
+ */
+
+template<typename ForwardIterator,typename OutputIterator>
+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); /* close remaining context */
+}
+
+/* Without these explicit instantiations, MSVC++ 6.5/7.0 does not
+ * find some friend operators in certain contexts.
+ */
+
+character dummy1;
+html_tag dummy2;
+
+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 "<<in<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ typedef std::istreambuf_iterator<char> istrbuf_iterator;
+ std::vector<char> html_source;
+ std::copy(
+ istrbuf_iterator(ifs),istrbuf_iterator(),
+ std::back_inserter(html_source));
+
+ /* parse the HTML */
+
+ std::vector<character> scanned_html;
+ scan_html(
+ html_source.begin(),html_source.end(),std::back_inserter(scanned_html));
+
+ /* Now that we have the text as a vector of contextualized characters,
+ * we can shuffle it around and manipulate in almost any way we please.
+ * For instance, the following reverses the central portion of the doc.
+ */
+
+ std::reverse(
+ scanned_html.begin()+scanned_html.size()/4,
+ scanned_html.begin()+3*(scanned_html.size()/4));
+
+ /* emit the resulting HTML */
+
+ 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 "<<out<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ typedef std::ostreambuf_iterator<char> ostrbuf_iterator;
+ produce_html(scanned_html.begin(),scanned_html.end(),ostrbuf_iterator(ofs));
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/key_value.cpp b/src/boost/libs/flyweight/example/key_value.cpp
new file mode 100644
index 000000000..5a93d07fe
--- /dev/null
+++ b/src/boost/libs/flyweight/example/key_value.cpp
@@ -0,0 +1,99 @@
+/* Boost.Flyweight example of use of key-value flyweights.
+ *
+ * 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 <boost/array.hpp>
+#include <boost/flyweight.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <cstdlib>
+#include <iostream>
+#include <string>
+#include <vector>
+
+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 "<<filename<<" file"<<std::endl;
+ }
+
+ texture(const texture& x):filename(x.filename)
+ {
+ std::cout<<"texture["<<filename<<"] copied"<<std::endl;
+ }
+
+ ~texture()
+ {
+ std::cout<<"unloaded "<<filename<<std::endl;
+ }
+
+ const std::string& get_filename()const{return filename;}
+
+ // rest of the interface
+
+private:
+ std::string filename;
+};
+
+/* key extractor of filename strings from textures */
+
+struct texture_filename_extractor
+{
+ const std::string& operator()(const texture& x)const
+ {
+ return x.get_filename();
+ }
+};
+
+/* texture flyweight */
+
+typedef flyweight<
+ key_value<std::string,texture,texture_filename_extractor>
+> 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"<<std::endl;
+
+ std::vector<texture_flyweight> 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"<<textures.size()<<" flyweights created\n"<<std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/perf.cpp b/src/boost/libs/flyweight/example/perf.cpp
new file mode 100644
index 000000000..3e608c0db
--- /dev/null
+++ b/src/boost/libs/flyweight/example/perf.cpp
@@ -0,0 +1,312 @@
+/* Boost.Flyweight example of performance comparison.
+ *
+ * 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 <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/hashed_factory.hpp>
+#include <boost/flyweight/set_factory.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/no_tracking.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/tokenizer.hpp>
+#include <algorithm>
+#include <cstddef>
+#include <cstdlib>
+#include <ctime>
+#include <fstream>
+#include <iostream>
+#include <numeric>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+using ::clock;
+using ::clock_t;
+using ::exit;
+}
+#endif
+
+using namespace boost::flyweights;
+
+/* Instrumented allocator family keeping track of the memory in
+ * current use.
+ */
+
+std::size_t count_allocator_mem=0;
+
+template<typename T>
+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;
+ template<class U>struct rebind{typedef count_allocator<U> other;};
+
+ count_allocator(){}
+ count_allocator(const count_allocator<T>&){}
+ template<class U>count_allocator(const count_allocator<U>&,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;
+ }
+};
+
+template<>
+class count_allocator<void>
+{
+public:
+ typedef void* pointer;
+ typedef const void* const_pointer;
+ typedef void value_type;
+ template<class U>struct rebind{typedef count_allocator<U> other;};
+};
+
+/* Define some count_allocator-based types and Boost.Flyweight components */
+
+typedef std::basic_string<
+ char,std::char_traits<char>,count_allocator<char>
+> count_string;
+
+typedef hashed_factory<
+ boost::hash<boost::mpl::_2>,
+ std::equal_to<boost::mpl::_2>,
+ count_allocator<boost::mpl::_1>
+> count_hashed_factory;
+
+typedef set_factory<
+ std::less<boost::mpl::_2>,
+ count_allocator<boost::mpl::_1>
+> count_set_factory;
+
+/* Some additional utilities used by the test routine */
+
+class timer
+{
+public:
+ timer(){restart();}
+
+ void restart(){t=std::clock();}
+
+ void time(const char* str)
+ {
+ std::cout<<str<<": "<<(double)(std::clock()-t)/CLOCKS_PER_SEC<<" s\n";
+ }
+
+private:
+ std::clock_t t;
+};
+
+template<typename T>
+struct is_flyweight:
+ boost::mpl::false_{};
+
+template<
+ typename T,
+ typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
+>
+struct is_flyweight<flyweight<T,Arg1,Arg2,Arg3,Arg4,Arg5> >:
+ boost::mpl::true_{};
+
+struct length_adder
+{
+ std::size_t operator()(std::size_t n,const count_string& x)const
+ {
+ return n+x.size();
+ }
+};
+
+/* Measure time and memory performance for a String, which is assumed
+ * to be either a plain string type or a string flyweight.
+ */
+
+template<typename String>
+struct test
+{
+ static std::size_t run(const std::string& file)
+ {
+ typedef std::vector<String,count_allocator<String> > count_vector;
+
+ /* Define a tokenizer on std::istreambuf. */
+
+ typedef std::istreambuf_iterator<char> char_iterator;
+ typedef boost::tokenizer<
+ boost::char_separator<char>,
+ char_iterator
+ > tokenizer;
+
+ std::ifstream ifs(file.c_str());
+ if(!ifs){
+ std::cout<<"can't open "<<file<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ /* Initialization; tokenize using space and common punctuaction as
+ * separators, and keeping the separators.
+ */
+
+ timer t;
+
+ tokenizer tok=tokenizer(
+ char_iterator(ifs),char_iterator(),
+ boost::char_separator<char>(
+ "",
+ "\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");
+
+ /* Assignment */
+
+ t.restart();
+
+ count_vector txt2;
+ for(int i=0;i<10;++i){
+ txt2.insert(txt2.end(),txt.begin(),txt.end());
+ }
+
+ t.time("assignment time");
+
+ /* Equality comparison */
+
+ 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");
+
+ /* Value access */
+
+ 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");
+
+ std::cout<<"bytes used: "<<count_allocator_mem;
+ if(is_flyweight<String>::value){
+ std::size_t flyweight_mem=(txt.capacity()+txt2.capacity())*sizeof(String);
+ std::cout<<"= flyweights("<<flyweight_mem
+ <<")+values("<<count_allocator_mem-flyweight_mem<<")";
+ }
+ std::cout<<"\n";
+
+ return c+s;
+ }
+};
+
+/* table of test cases for the user to select from */
+
+struct test_case
+{
+ const char* name;
+ std::size_t (*test)(const std::string&);
+};
+
+test_case test_table[]=
+{
+ {
+ "simple string",
+ test<count_string>::run
+ },
+ {
+ "flyweight, hashed factory",
+ test<flyweight<count_string,count_hashed_factory> >::run
+ },
+ {
+ "flyweight, hashed factory, no tracking",
+ test<flyweight<count_string,count_hashed_factory,no_tracking> >::run
+ },
+ {
+ "flyweight, set-based factory",
+ test<flyweight<count_string,count_set_factory> >::run
+ },
+ {
+ "flyweight, set-based factory, no tracking",
+ test<flyweight<count_string,count_set_factory,no_tracking> >::run
+ }
+};
+
+const int num_test_cases=sizeof(test_table)/sizeof(test_case);
+
+int main()
+{
+ try{
+ for(int i=0;i<num_test_cases;++i){
+ std::cout<<i+1<<". "<<test_table[i].name<<"\n";
+ }
+ int option=-1;
+ for(;;){
+ std::cout<<"select option, enter to exit: ";
+ std::string str;
+ std::getline(std::cin,str);
+ if(str.empty())std::exit(EXIT_SUCCESS);
+ std::istringstream istr(str);
+ istr>>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: "<<e.what()<<"\n";
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/example/serialization.cpp b/src/boost/libs/flyweight/example/serialization.cpp
new file mode 100644
index 000000000..80227a539
--- /dev/null
+++ b/src/boost/libs/flyweight/example/serialization.cpp
@@ -0,0 +1,133 @@
+/* Boost.Flyweight example of serialization.
+ *
+ * Copyright 2006-2014 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/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <algorithm>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/flyweight.hpp>
+#include <boost/flyweight/serialize.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/tokenizer.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+using namespace boost::flyweights;
+
+typedef flyweight<std::string> fw_string;
+typedef std::vector<fw_string> text_container;
+
+/* Read a text file into a text_container and serialize to an archive. */
+
+void save_serialization_file()
+{
+ /* Define a tokenizer on std::istreambuf. */
+
+ typedef std::istreambuf_iterator<char> char_iterator;
+ typedef boost::tokenizer<
+ boost::char_separator<char>,
+ 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 "<<in<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ /* Tokenize using space and common punctuaction as separators, and
+ * keeping the separators.
+ */
+
+ tokenizer tok=tokenizer(
+ char_iterator(ifs),char_iterator(),
+ boost::char_separator<char>(
+ "",
+ "\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 "<<out<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ boost::archive::text_oarchive oa(ofs);
+ oa<<const_cast<const text_container&>(txt);
+}
+
+/* Read a serialization archive and save the result to a text file. */
+
+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 "<<in<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ boost::archive::text_iarchive ia(ifs);
+ text_container txt;
+ ia>>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 "<<out<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+ std::copy(
+ txt.begin(),txt.end(),
+ std::ostream_iterator<std::string>(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: "<<e.what()<<std::endl;
+ std::exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/flyweight/index.html b/src/boost/libs/flyweight/index.html
new file mode 100644
index 000000000..1a861cf7b
--- /dev/null
+++ b/src/boost/libs/flyweight/index.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0.1 Transitional//EN">
+<!--
+ Copyright 2006 Joaquín M López Muñoz.
+ 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)
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<meta http-equiv="refresh" content="0; URL=doc/index.html">
+<title>Boost.Flyweight Documentation</title>
+<link rel="stylesheet" href="doc/style.css" type="text/css">
+</head>
+
+<body>
+Automatic redirection failed, please go to
+<a href="doc/index.html">doc/index.html</a>
+</body>
+</html>
diff --git a/src/boost/libs/flyweight/meta/libraries.json b/src/boost/libs/flyweight/meta/libraries.json
new file mode 100644
index 000000000..38a820e3e
--- /dev/null
+++ b/src/boost/libs/flyweight/meta/libraries.json
@@ -0,0 +1,15 @@
+{
+ "key": "flyweight",
+ "name": "Flyweight",
+ "authors": [
+ "Joaqu\u00edn M L\u00f3pez Mu\u00f1oz"
+ ],
+ "description": "Design pattern to manage large quantities of highly redundant objects.",
+ "category": [
+ "Patterns"
+ ],
+ "maintainers": [
+ "Joaquin M Lopez Munoz <joaquin.lopezmunoz -at- gmail.com>"
+ ],
+ "cxxstd": "03"
+}
diff --git a/src/boost/libs/flyweight/test/Jamfile.v2 b/src/boost/libs/flyweight/test/Jamfile.v2
new file mode 100644
index 000000000..e18eb8f90
--- /dev/null
+++ b/src/boost/libs/flyweight/test/Jamfile.v2
@@ -0,0 +1,36 @@
+# Boost.Flyweight tests Jamfile
+#
+# Copyright 2006-2014 Joaquín M López Muñoz.
+# 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.
+
+project
+ : requirements
+ <os>LINUX:<threading>multi
+ ;
+
+test-suite "flyweight" :
+ [ run test_assoc_cont_factory.cpp test_assoc_cont_fact_main.cpp ]
+ [ run test_basic.cpp test_basic_main.cpp ]
+ [ run test_custom_factory.cpp test_custom_factory_main.cpp ]
+ [ run test_init.cpp test_init_main.cpp ]
+ [ run test_intermod_holder.cpp test_intermod_holder_main.cpp
+ intermod_holder_dll
+ : # command line
+ : # input files
+ : # requirements
+ <threading>multi ]
+ [ run test_multictor.cpp test_multictor_main.cpp ]
+ [ run test_no_locking.cpp test_no_locking_main.cpp ]
+ [ run test_no_tracking.cpp test_no_tracking_main.cpp ]
+ [ run test_serialization.cpp test_serialization_main.cpp
+ /boost/serialization//boost_serialization/<link>static ]
+ [ run test_set_factory.cpp test_set_factory_main.cpp ]
+ ;
+
+lib intermod_holder_dll : intermod_holder_dll.cpp :
+ <link>shared
+ <define>BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_SOURCE=1 ;
diff --git a/src/boost/libs/flyweight/test/heavy_objects.hpp b/src/boost/libs/flyweight/test/heavy_objects.hpp
new file mode 100644
index 000000000..142e96b7c
--- /dev/null
+++ b/src/boost/libs/flyweight/test/heavy_objects.hpp
@@ -0,0 +1,106 @@
+/* Classes for Boost.Flyweight key-value tests.
+ *
+ * Copyright 2006-2014 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.
+ */
+
+#ifndef BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP
+#define BOOST_FLYWEIGHT_TEST_HEAVY_OBJECTS_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/noncopyable.hpp>
+#include <iosfwd>
+#include <string>
+
+struct texture
+{
+ texture(const std::string& str_=""):str(str_){}
+
+ friend bool operator==(
+ const texture& x,const texture& y){return x.str==y.str;}
+ friend bool operator< (
+ const texture& x,const texture& y){return x.str< y.str;}
+ friend bool operator!=(
+ const texture& x,const texture& y){return x.str!=y.str;}
+ friend bool operator> (
+ const texture& x,const texture& y){return x.str> y.str;}
+ friend bool operator>=(
+ const texture& x,const texture& y){return x.str>=y.str;}
+ friend bool operator<=(
+ const texture& x,const texture& y){return x.str<=y.str;}
+
+ friend std::ostream& operator<<(std::ostream& os,const texture& x)
+ {
+ return os<<x.str;
+ }
+
+ friend std::istream& operator>>(std::istream& is,texture& x)
+ {
+ return is>>x.str;
+ }
+
+ std::string str;
+};
+
+struct from_texture_to_string
+{
+ const std::string& operator()(const texture& x)const{return x.str;}
+};
+
+struct factorization:private boost::noncopyable
+{
+ factorization(int n_=0):n(n_){}
+
+ friend bool operator==(
+ const factorization& x,const factorization& y){return x.n==y.n;}
+ friend bool operator< (
+ const factorization& x,const factorization& y){return x.n< y.n;}
+ friend bool operator!=(
+ const factorization& x,const factorization& y){return x.n!=y.n;}
+ friend bool operator> (
+ const factorization& x,const factorization& y){return x.n> y.n;}
+ friend bool operator>=(
+ const factorization& x,const factorization& y){return x.n>=y.n;}
+ friend bool operator<=(
+ const factorization& x,const factorization& y){return x.n<=y.n;}
+
+ friend std::ostream& operator<<(std::ostream& os,const factorization& x)
+ {
+ return os<<x.n;
+ }
+
+ friend std::istream& operator>>(std::istream& is,factorization& x)
+ {
+ return is>>x.n;
+ }
+
+ int n;
+};
+
+#if !defined(BOOST_NO_EXCEPTIONS)
+struct throwing_value_exception{};
+
+struct throwing_value
+{
+ throwing_value():n(0){}
+ throwing_value(const throwing_value&){throw throwing_value_exception();}
+ throwing_value(int){throw throwing_value_exception();}
+
+ int n;
+};
+
+struct from_throwing_value_to_int
+{
+ const int& operator()(const throwing_value& x)const{return x.n;}
+};
+#endif
+
+#endif
diff --git a/src/boost/libs/flyweight/test/intermod_holder_dll.cpp b/src/boost/libs/flyweight/test/intermod_holder_dll.cpp
new file mode 100644
index 000000000..098bca322
--- /dev/null
+++ b/src/boost/libs/flyweight/test/intermod_holder_dll.cpp
@@ -0,0 +1,17 @@
+/* Boost.Flyweight test of intermodule_holder.
+ *
+ * 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 "intermod_holder_dll.hpp"
+
+intermodule_flyweight_string create_intermodule_flyweight_string(
+ const std::string& str)
+{
+ return intermodule_flyweight_string(str);
+}
diff --git a/src/boost/libs/flyweight/test/intermod_holder_dll.hpp b/src/boost/libs/flyweight/test/intermod_holder_dll.hpp
new file mode 100644
index 000000000..4df7ff8c2
--- /dev/null
+++ b/src/boost/libs/flyweight/test/intermod_holder_dll.hpp
@@ -0,0 +1,41 @@
+/* Boost.Flyweight test of intermodule_holder.
+ *
+ * Copyright 2006-2018 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.
+ */
+
+#ifndef BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_HPP
+#define BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/hashed_factory.hpp>
+#include <boost/flyweight/intermodule_holder.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <string>
+
+#ifdef BOOST_FLYWEIGHT_TEST_INTERMOD_HOLDER_DLL_SOURCE
+#define BOOST_FLYWEIGHT_DLL_DECL BOOST_SYMBOL_EXPORT
+#else
+#define BOOST_FLYWEIGHT_DLL_DECL BOOST_SYMBOL_IMPORT
+#endif
+
+typedef boost::flyweights::flyweight<
+ std::string,
+ boost::flyweights::intermodule_holder> intermodule_flyweight_string;
+
+BOOST_FLYWEIGHT_DLL_DECL intermodule_flyweight_string
+create_intermodule_flyweight_string(const std::string&);
+
+#undef BOOST_FLYWEIGHT_DLL_DECL
+
+#endif
diff --git a/src/boost/libs/flyweight/test/test_all_main.cpp b/src/boost/libs/flyweight/test/test_all_main.cpp
new file mode 100644
index 000000000..737f95a8f
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_all_main.cpp
@@ -0,0 +1,38 @@
+/* Boost.Flyweight test suite.
+ *
+ * Copyright 2006-2014 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/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include "test_assoc_cont_factory.hpp"
+#include "test_basic.hpp"
+#include "test_custom_factory.hpp"
+#include "test_intermod_holder.hpp"
+#include "test_init.hpp"
+#include "test_multictor.hpp"
+#include "test_no_locking.hpp"
+#include "test_no_tracking.hpp"
+#include "test_serialization.hpp"
+#include "test_set_factory.hpp"
+
+int main()
+{
+ test_assoc_container_factory();
+ test_basic();
+ test_custom_factory();
+ test_init();
+ test_intermodule_holder();
+ test_multictor();
+ test_no_locking();
+ test_no_tracking();
+ test_serialization();
+ test_set_factory();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_assoc_cont_fact_main.cpp b/src/boost/libs/flyweight/test/test_assoc_cont_fact_main.cpp
new file mode 100644
index 000000000..1b3e7b71d
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_assoc_cont_fact_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of assoc_container_factory.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_assoc_cont_factory.hpp"
+
+int main()
+{
+ test_assoc_container_factory();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_assoc_cont_factory.cpp b/src/boost/libs/flyweight/test/test_assoc_cont_factory.cpp
new file mode 100644
index 000000000..078ff4aec
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_assoc_cont_factory.cpp
@@ -0,0 +1,91 @@
+/* Boost.Flyweight test of assoc_container_factory.
+ *
+ * Copyright 2006-2018 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 "test_assoc_cont_factory.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/assoc_container_factory.hpp>
+#include <boost/flyweight/detail/is_placeholder_expr.hpp>
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include <boost/mpl/if.hpp>
+#include <functional>
+#include <set>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct reverse_set_specifier
+{
+ template<typename Entry,typename Key>
+ struct apply
+ {
+ typedef std::set<Entry,std::greater<Key> > type;
+ };
+};
+
+struct assoc_container_factory_flyweight_specifier1
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ assoc_container_factory<reverse_set_specifier>
+ > type;
+ };
+};
+
+/* flyweight<..., assoc_container_factory_class<std::set<...> >, ...> pulls
+ * the type std::set<...> in as part of its associated ADL set and causes it
+ * to be instantiated when doing any unqualified function call like, for
+ * instance, comparing flyweights for equality, which can trigger a static
+ * assertion in concept-checked STL implementations when std::set<...> is an
+ * MPL placeholder expression. We avoid this mess with protected_set<...>.
+ */
+
+struct protected_set_empty_base{};
+
+template<typename K,typename C,typename A>
+struct protected_set:
+ boost::mpl::if_c<
+ boost::flyweights::detail::is_placeholder_expression<
+ protected_set<K,C,A>
+ >::value,
+ protected_set_empty_base,
+ std::set<K,C,A>
+ >::type
+{};
+
+struct assoc_container_factory_flyweight_specifier2
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ assoc_container_factory_class<
+ protected_set<
+ boost::mpl::_1,
+ std::greater<boost::mpl::_2>,
+ std::allocator<boost::mpl::_1>
+ >
+ >
+ > type;
+ };
+};
+
+void test_assoc_container_factory()
+{
+ test_basic_template<assoc_container_factory_flyweight_specifier1>();
+ test_basic_template<assoc_container_factory_flyweight_specifier2>();
+}
diff --git a/src/boost/libs/flyweight/test/test_assoc_cont_factory.hpp b/src/boost/libs/flyweight/test/test_assoc_cont_factory.hpp
new file mode 100644
index 000000000..e9aa9313d
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_assoc_cont_factory.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of assoc_container_factory.
+ *
+ * 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.
+ */
+
+void test_assoc_container_factory();
diff --git a/src/boost/libs/flyweight/test/test_basic.cpp b/src/boost/libs/flyweight/test/test_basic.cpp
new file mode 100644
index 000000000..53285ec22
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_basic.cpp
@@ -0,0 +1,68 @@
+/* Boost.Flyweight basic test.
+ *
+ * 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 "test_basic.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight.hpp>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct basic_flyweight_specifier1
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T> type;
+ };
+};
+
+struct basic_flyweight_specifier2
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,tag<int>,
+ static_holder_class<boost::mpl::_1>,
+ hashed_factory_class<
+ boost::mpl::_1,boost::mpl::_2,
+ boost::hash<boost::mpl::_2>,std::equal_to<boost::mpl::_2>,
+ std::allocator<boost::mpl::_1>
+ >,
+ simple_locking,
+ refcounted
+ > type;
+ };
+};
+
+struct basic_flyweight_specifier3
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ hashed_factory<
+ boost::hash<boost::mpl::_2>,std::equal_to<boost::mpl::_2>,
+ std::allocator<boost::mpl::_1>
+ >,
+ tag<int>
+ > type;
+ };
+};
+
+void test_basic()
+{
+ test_basic_template<basic_flyweight_specifier1>();
+ test_basic_template<basic_flyweight_specifier2>();
+ test_basic_template<basic_flyweight_specifier3>();
+}
diff --git a/src/boost/libs/flyweight/test/test_basic.hpp b/src/boost/libs/flyweight/test/test_basic.hpp
new file mode 100644
index 000000000..d7d86d5f1
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_basic.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight basic test.
+ *
+ * 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.
+ */
+
+void test_basic();
diff --git a/src/boost/libs/flyweight/test/test_basic_main.cpp b/src/boost/libs/flyweight/test/test_basic_main.cpp
new file mode 100644
index 000000000..b2508d85c
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_basic_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight basic test.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_basic.hpp"
+
+int main()
+{
+ test_basic();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_basic_template.hpp b/src/boost/libs/flyweight/test/test_basic_template.hpp
new file mode 100644
index 000000000..61b462be4
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_basic_template.hpp
@@ -0,0 +1,304 @@
+/* Boost.Flyweight basic test template.
+ *
+ * Copyright 2006-2019 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.
+ */
+
+#ifndef BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
+#define BOOST_FLYWEIGHT_TEST_BASIC_TEMPLATE_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/utility/value_init.hpp>
+#include <string>
+#include <sstream>
+#include "heavy_objects.hpp"
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#include <utility>
+#endif
+
+#if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
+#include <boost/functional/hash.hpp>
+
+#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
+#include <functional>
+#endif
+#endif
+
+#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
+
+template<typename Flyweight,typename ForwardIterator>
+void test_basic_template(
+ ForwardIterator first,ForwardIterator last
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
+{
+ typedef typename Flyweight::value_type value_type;
+
+ ForwardIterator it;
+
+ for(it=first;it!=last;++it){
+ /* construct/copy/destroy */
+
+ Flyweight f1(*it);
+ Flyweight f2;
+ Flyweight c1(f1);
+ const Flyweight c2(static_cast<const Flyweight&>(f2));
+ value_type v1(*it);
+ boost::value_initialized<value_type> v2;
+ BOOST_TEST(f1.get_key()==*it);
+ BOOST_TEST((f1==f2)==(f1.get()==v2.data()));
+ BOOST_TEST(f1==c1);
+ BOOST_TEST(f2==c2);
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ Flyweight cr1(std::move(c1));
+ Flyweight cr2(std::move(c2));
+ BOOST_TEST(f1==cr1);
+ BOOST_TEST(f2==cr2);
+#endif
+
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+ /* testcase for https://svn.boost.org/trac/boost/ticket/10439 */
+
+ Flyweight f3={};
+ BOOST_TEST(f3==f2);
+#endif
+
+ f1=((void)0,f1); /* self assignment warning */
+ BOOST_TEST(f1==f1);
+
+ c1=f2;
+ BOOST_TEST(c1==f2);
+
+ c1=f1;
+ BOOST_TEST(c1==f1);
+
+ /* convertibility to underlying type */
+
+ BOOST_TEST(f1.get()==v1);
+
+ /* identity of reference */
+
+ BOOST_TEST(&f1.get()==&c1.get());
+
+ /* modifiers */
+
+ f1.swap(f1);
+ BOOST_TEST(f1==c1);
+
+ f1.swap(f2);
+ BOOST_TEST(f1==c2);
+ BOOST_TEST(f2==c1);
+
+ boost::flyweights::swap(f1,f2);
+ BOOST_TEST(f1==c1);
+ BOOST_TEST(f2==c2);
+
+ /* specialized algorithms */
+
+ std::ostringstream oss1;
+ oss1<<f1;
+ std::ostringstream oss2;
+ oss2<<f1.get();
+ BOOST_TEST(oss1.str()==oss2.str());
+
+#if !defined(BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT)
+
+ /* hash support */
+
+ BOOST_TEST(boost::hash<Flyweight>()(f1)==boost::hash<Flyweight>()(c1));
+ BOOST_TEST(boost::hash<Flyweight>()(f1)==
+ boost::hash<const value_type*>()(&f1.get()));
+
+#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
+ BOOST_TEST(std::hash<Flyweight>()(f1)==std::hash<Flyweight>()(c1));
+ BOOST_TEST(std::hash<Flyweight>()(f1)==
+ std::hash<const value_type*>()(&f1.get()));
+#endif
+#endif
+ }
+}
+
+template<typename Flyweight,typename ForwardIterator>
+void test_basic_with_assign_template(
+ ForwardIterator first,ForwardIterator last
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
+{
+ typedef typename Flyweight::value_type value_type;
+
+ ForwardIterator it;
+
+ test_basic_template<Flyweight>(first,last);
+
+ for(it=first;it!=last;++it){
+ /* value construction */
+
+ value_type v(*it);
+ Flyweight f1(v);
+ Flyweight f2(f1.get());
+ BOOST_TEST(f1.get()==v);
+ BOOST_TEST(f2.get()==v);
+ BOOST_TEST(f1==f2);
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ value_type v1(v);
+ const value_type v2(v);
+ Flyweight fr1(std::move(v1));
+ Flyweight fr2(std::move(v2));
+ BOOST_TEST(fr1==v);
+ BOOST_TEST(fr2==v);
+#endif
+
+ /* value assignment */
+
+ Flyweight f3,f4;
+ f3=v;
+ f4=f1.get();
+ BOOST_TEST(f2.get()==v);
+ BOOST_TEST(f3.get()==v);
+ BOOST_TEST(f2==f3);
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ Flyweight fr3;
+ fr3=value_type(*it);
+ BOOST_TEST(fr3.get()==value_type(*it));
+#endif
+
+ /* specialized algorithms */
+
+ std::ostringstream oss1;
+ oss1<<f1;
+ std::istringstream iss1(oss1.str());
+ Flyweight f5;
+ iss1>>f5;
+ BOOST_TEST(f5==f1);
+ }
+}
+
+template<
+ typename Flyweight1,typename Flyweight2,
+ typename ForwardIterator1,typename ForwardIterator2
+>
+void test_basic_comparison_template(
+ ForwardIterator1 first1,ForwardIterator1 last1,
+ ForwardIterator2 first2
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight1)
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight2))
+{
+ typedef typename Flyweight1::value_type value_type1;
+ typedef typename Flyweight2::value_type value_type2;
+
+ for(;first1!=last1;++first1,++first2){
+ value_type1 v1=value_type1(*first1);
+ value_type2 v2=value_type2(*first2);
+ Flyweight1 f1(v1);
+ Flyweight2 f2(v2);
+
+ BOOST_TEST((f1==f2)==(f1.get()==v2));
+ BOOST_TEST((f1< f2)==(f1.get()< v2));
+ BOOST_TEST((f1!=f2)==(f1.get()!=v2));
+ BOOST_TEST((f1> f2)==(f1.get()> v2));
+ BOOST_TEST((f1>=f2)==(f1.get()>=v2));
+ BOOST_TEST((f1<=f2)==(f1.get()<=v2));
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+ BOOST_TEST((f1==v2)==(f1.get()==v2));
+ BOOST_TEST((f1< v2)==(f1.get()< v2));
+ BOOST_TEST((f1!=v2)==(f1.get()!=v2));
+ BOOST_TEST((f1> v2)==(f1.get()> v2));
+ BOOST_TEST((f1>=v2)==(f1.get()>=v2));
+ BOOST_TEST((f1<=v2)==(f1.get()<=v2));
+
+ BOOST_TEST((v1==f2)==(f1.get()==v2));
+ BOOST_TEST((v1< f2)==(f1.get()< v2));
+ BOOST_TEST((v1!=f2)==(f1.get()!=v2));
+ BOOST_TEST((v1> f2)==(f1.get()> v2));
+ BOOST_TEST((v1>=f2)==(f1.get()>=v2));
+ BOOST_TEST((v1<=f2)==(f1.get()<=v2));
+#endif
+
+ }
+}
+
+template<typename FlyweightSpecifier>
+void test_basic_template(BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier))
+{
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,int
+ >::type int_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,std::string
+ >::type string_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,char
+ >::type char_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,
+ boost::flyweights::key_value<std::string,texture,from_texture_to_string>
+ >::type texture_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,
+ boost::flyweights::key_value<int,factorization>
+ >::type factorization_flyweight;
+
+ int ints[]={0,1,1,0,1,2,3,4,3,4,0,0};
+ test_basic_with_assign_template<int_flyweight>(
+ &ints[0],&ints[0]+LENGTHOF(ints));
+
+ const char* words[]={"hello","boost","flyweight","boost","bye","c++","c++"};
+ test_basic_with_assign_template<string_flyweight>(
+ &words[0],&words[0]+LENGTHOF(words));
+
+ const char* textures[]={"wood","grass","sand","granite","terracotta"};
+ test_basic_with_assign_template<texture_flyweight>(
+ &textures[0],&textures[0]+LENGTHOF(textures));
+
+ int factorizations[]={1098,102387,90846,2223978};
+ test_basic_template<factorization_flyweight>(
+ &factorizations[0],&factorizations[0]+LENGTHOF(factorizations));
+
+ char chars[]={0,2,4,5,1,1,1,3,4,1,1,0};
+ test_basic_comparison_template<int_flyweight,char_flyweight>(
+ &ints[0],&ints[0]+LENGTHOF(ints),&chars[0]);
+
+ test_basic_comparison_template<string_flyweight,string_flyweight>(
+ &words[0],&words[0]+LENGTHOF(words)-1,&words[1]);
+
+ test_basic_comparison_template<texture_flyweight,texture_flyweight>(
+ &textures[0],&textures[0]+LENGTHOF(textures)-1,&textures[1]);
+
+#if !defined(BOOST_NO_EXCEPTIONS)
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,
+ boost::flyweights::key_value<int,throwing_value,from_throwing_value_to_int>
+ >::type throwing_flyweight;
+
+ try{
+ throwing_flyweight fw(0);
+ }catch(const throwing_value_exception&){}
+ try{
+ throwing_flyweight fw=throwing_flyweight(throwing_value());
+ (void)fw;
+ }catch(const throwing_value_exception&){}
+#endif
+
+}
+
+#undef LENGTHOF
+
+#endif
diff --git a/src/boost/libs/flyweight/test/test_custom_factory.cpp b/src/boost/libs/flyweight/test/test_custom_factory.cpp
new file mode 100644
index 000000000..9fec1b408
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_custom_factory.cpp
@@ -0,0 +1,111 @@
+/* Boost.Flyweight test of a custom factory.
+ *
+ * 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 "test_custom_factory.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <list>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+/* Info on list-update containers:
+ * http://gcc.gnu.org/onlinedocs/libstdc++/ext/pb_ds/lu_based_containers.html
+ */
+
+template<typename Entry,typename Key>
+class lu_factory_class:public factory_marker
+{
+ struct entry_type
+ {
+ entry_type(const Entry& x_):x(x_),count(0){}
+
+ Entry x;
+ std::size_t count;
+ };
+
+ typedef std::list<entry_type> container_type;
+
+public:
+ typedef typename container_type::iterator handle_type;
+
+ handle_type insert(const Entry& x)
+ {
+ handle_type h;
+ for(h=cont.begin();h!=cont.end();++h){
+ if(static_cast<const Key&>(h->x)==static_cast<const Key&>(x)){
+ if(++(h->count)==10){
+ h->count=0;
+ cont.splice(cont.begin(),cont,h); /* move to front */
+ }
+ return h;
+ }
+ }
+ cont.push_back(entry_type(x));
+ h=cont.end();
+ --h;
+ return h;
+ }
+
+ void erase(handle_type h)
+ {
+ cont.erase(h);
+ }
+
+ const Entry& entry(handle_type h){return h->x;}
+
+private:
+ container_type cont;
+
+public:
+ typedef lu_factory_class type;
+ BOOST_MPL_AUX_LAMBDA_SUPPORT(2,lu_factory_class,(Entry,Key))
+};
+
+struct lu_factory:factory_marker
+{
+ template<typename Entry,typename Key>
+ struct apply
+ {
+ typedef lu_factory_class<Entry,Key> type;
+ };
+};
+
+struct custom_factory_flyweight_specifier1
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T,lu_factory> type;
+ };
+};
+
+struct custom_factory_flyweight_specifier2
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ lu_factory_class<boost::mpl::_1,boost::mpl::_2>
+ > type;
+ };
+};
+
+void test_custom_factory()
+{
+ test_basic_template<custom_factory_flyweight_specifier1>();
+ test_basic_template<custom_factory_flyweight_specifier2>();
+}
diff --git a/src/boost/libs/flyweight/test/test_custom_factory.hpp b/src/boost/libs/flyweight/test/test_custom_factory.hpp
new file mode 100644
index 000000000..5b17deb16
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_custom_factory.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of a custom factory.
+ *
+ * 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.
+ */
+
+void test_custom_factory();
diff --git a/src/boost/libs/flyweight/test/test_custom_factory_main.cpp b/src/boost/libs/flyweight/test/test_custom_factory_main.cpp
new file mode 100644
index 000000000..95067035d
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_custom_factory_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of a custom factory.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_custom_factory.hpp"
+
+int main()
+{
+ test_custom_factory();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_init.cpp b/src/boost/libs/flyweight/test/test_init.cpp
new file mode 100644
index 000000000..5421b8085
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_init.cpp
@@ -0,0 +1,49 @@
+/* Boost.Flyweight test of static data initialization facilities.
+ *
+ * Copyright 2006-2019 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 "test_init.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/flyweight.hpp>
+
+using namespace boost::flyweights;
+
+template<bool* pmark,typename Entry,typename Value>
+struct marked_hashed_factory_class:hashed_factory_class<Entry,Value>
+{
+ marked_hashed_factory_class(){*pmark=true;}
+};
+
+template<bool* pmark>
+struct marked_hashed_factory:factory_marker
+{
+ template<typename Entry,typename Value>
+ struct apply
+ {
+ typedef marked_hashed_factory_class<pmark,Entry,Value> type;
+ };
+};
+
+namespace boost_flyweight_test{
+
+bool mark1=false;
+bool init1=flyweight<int,marked_hashed_factory<&mark1> >::init();
+
+bool mark2=false;
+flyweight<int,marked_hashed_factory<&mark2> >::initializer init2;
+
+}
+
+void test_init()
+{
+ BOOST_TEST(boost_flyweight_test::mark1);
+ BOOST_TEST(boost_flyweight_test::mark2);
+}
diff --git a/src/boost/libs/flyweight/test/test_init.hpp b/src/boost/libs/flyweight/test/test_init.hpp
new file mode 100644
index 000000000..4e869f540
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_init.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of static data initialization facilities.
+ *
+ * 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.
+ */
+
+void test_init();
diff --git a/src/boost/libs/flyweight/test/test_init_main.cpp b/src/boost/libs/flyweight/test/test_init_main.cpp
new file mode 100644
index 000000000..213e50513
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_init_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of static data initialization facilities.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_init.hpp"
+
+int main()
+{
+ test_init();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_intermod_holder.cpp b/src/boost/libs/flyweight/test/test_intermod_holder.cpp
new file mode 100644
index 000000000..65ca1c1d9
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_intermod_holder.cpp
@@ -0,0 +1,34 @@
+/* Boost.Flyweight test of intermodule_holder.
+ *
+ * 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 "test_intermod_holder.hpp"
+
+#include "intermod_holder_dll.hpp"
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct intermodule_holder_flyweight_specifier1
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T,intermodule_holder> type;
+ };
+};
+
+void test_intermodule_holder()
+{
+ test_basic_template<intermodule_holder_flyweight_specifier1>();
+
+ intermodule_flyweight_string str=
+ create_intermodule_flyweight_string("boost");
+ BOOST_TEST(str==intermodule_flyweight_string("boost"));
+}
diff --git a/src/boost/libs/flyweight/test/test_intermod_holder.hpp b/src/boost/libs/flyweight/test/test_intermod_holder.hpp
new file mode 100644
index 000000000..01495b3be
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_intermod_holder.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of intermodule_holder.
+ *
+ * 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.
+ */
+
+void test_intermodule_holder();
diff --git a/src/boost/libs/flyweight/test/test_intermod_holder_main.cpp b/src/boost/libs/flyweight/test/test_intermod_holder_main.cpp
new file mode 100644
index 000000000..11519cdc9
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_intermod_holder_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of intermodule_holder.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_intermod_holder.hpp"
+
+int main()
+{
+ test_intermodule_holder();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_multictor.cpp b/src/boost/libs/flyweight/test/test_multictor.cpp
new file mode 100644
index 000000000..2d1532ea7
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_multictor.cpp
@@ -0,0 +1,191 @@
+/* Boost.Flyweight test of flyweight forwarding and initializer_list ctors.
+ *
+ * Copyright 2006-2015 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 "test_multictor.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/flyweight.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+
+using boost::flyweight;
+
+#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
+#define NONCONST const
+#else
+#define NONCONST
+#endif
+
+struct multictor
+{
+ typedef multictor type;
+
+ multictor():
+ t(0,0,0.0,"",false){}
+ multictor(NONCONST int& x0):
+ t(x0,0,0.0,"",false){}
+ multictor(int x0,NONCONST char& x1):
+ t(x0,x1,0.0,"",false){}
+ multictor(int x0,char x1,NONCONST double& x2):
+ t(x0,x1,x2,"",false){}
+ multictor(int x0,char x1,double x2,NONCONST std::string& x3):
+ t(x0,x1,x2,x3,false){}
+ multictor(int x0,char x1,double x2,const std::string& x3,NONCONST bool& x4):
+ t(x0,x1,x2,x3,x4){}
+
+ friend bool operator==(const type& x,const type& y){return x.t==y.t;}
+ friend bool operator< (const type& x,const type& y){return x.t< y.t;}
+ friend bool operator!=(const type& x,const type& y){return x.t!=y.t;}
+ friend bool operator> (const type& x,const type& y){return x.t> y.t;}
+ friend bool operator>=(const type& x,const type& y){return x.t>=y.t;}
+ friend bool operator<=(const type& x,const type& y){return x.t<=y.t;}
+
+ boost::tuples::tuple<int,char,double,std::string,bool> t;
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const multictor& x)
+{
+ std::size_t res=0;
+ boost::hash_combine(res,boost::tuples::get<0>(x.t));
+ boost::hash_combine(res,boost::tuples::get<1>(x.t));
+ boost::hash_combine(res,boost::tuples::get<2>(x.t));
+ boost::hash_combine(res,boost::tuples::get<3>(x.t));
+ boost::hash_combine(res,boost::tuples::get<4>(x.t));
+ return res;
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+
+#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
+#define INIT0(_) {}
+#define INIT1(a) {a}
+#define INIT2(a,b) {a,b}
+#define INIT_LIST1(a) {a}
+#define INIT_LIST2(a,b) {a,b}
+#else
+#define INIT0(_)
+#define INIT1(a) ((a))
+#define INIT2(a,b) ((a),(b))
+#define INIT_LIST1(a) ({a})
+#define INIT_LIST2(a,b) ({a,b})
+#endif
+
+struct initctor
+{
+ struct arg{arg(int= 0){}};
+
+ initctor():res(-1){}
+ initctor(arg,arg):res(-2){}
+ initctor(int,unsigned int):res(-3){}
+
+ initctor(std::initializer_list<int> list):res(0)
+ {
+ typedef const int* iterator;
+ for(iterator it=list.begin(),it_end=list.end();it!=it_end;++it){
+ res+=*it;
+ }
+ }
+
+ initctor(std::initializer_list<unsigned int> list):res(0)
+ {
+ typedef const unsigned int* iterator;
+ for(iterator it=list.begin(),it_end=list.end();it!=it_end;++it){
+ res+=(int)(*it)*2;
+ }
+ }
+
+ friend bool operator==(const initctor& x,const initctor& y)
+ {
+ return x.res==y.res;
+ }
+
+ int res;
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const initctor& x)
+{
+ return (std::size_t)(x.res);
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+#endif
+
+void test_multictor()
+{
+ flyweight<multictor> f;
+ multictor m;
+ BOOST_TEST(f==m);
+
+ int x0=1;
+ flyweight<multictor> f0(x0);
+ multictor m0(x0);
+ BOOST_TEST(f0==m0);
+
+ char x1='a';
+ flyweight<multictor> f1(1,x1);
+ multictor m1(1,x1);
+ BOOST_TEST(f1==m1);
+
+ double x2=3.1416;
+ flyweight<multictor> f2(1,'a',x2);
+ multictor m2(1,'a',x2);
+ BOOST_TEST(f2==m2);
+
+ std::string x3("boost");
+ flyweight<multictor> f3(1,'a',3.1416,x3);
+ multictor m3(1,'a',3.1416,x3);
+ BOOST_TEST(f3==m3);
+
+ bool x4=true;
+ flyweight<multictor> f4(1,'a',3.1416,"boost",x4);
+ multictor m4(1,'a',3.1416,"boost",x4);
+ BOOST_TEST(f4==m4);
+
+#if !defined(BOOST_NO_SFINAE)&&!defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
+ flyweight<initctor> ff INIT0(~);
+ BOOST_TEST(ff.get().res==-1);
+
+ ff=flyweight<initctor> INIT2(initctor::arg(),1);
+ BOOST_TEST(ff.get().res==-2);
+
+ flyweight<initctor> ff0 INIT2(initctor::arg(),initctor::arg());
+ BOOST_TEST(ff0.get().res==-2);
+
+ ff0={1};
+ BOOST_TEST(ff0.get().res==1);
+
+ flyweight<initctor> ff1 INIT_LIST2(1,2);
+ BOOST_TEST(ff1.get().res==3);
+
+ ff1={1u,2u,3u};
+ BOOST_TEST(ff1.get().res==12);
+
+ flyweight<initctor> ff2 INIT_LIST1(1u);
+ BOOST_TEST(ff2.get().res==2);
+#endif
+}
diff --git a/src/boost/libs/flyweight/test/test_multictor.hpp b/src/boost/libs/flyweight/test/test_multictor.hpp
new file mode 100644
index 000000000..125cc9289
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_multictor.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of flyweight forwarding ctors.
+ *
+ * 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.
+ */
+
+void test_multictor();
diff --git a/src/boost/libs/flyweight/test/test_multictor_main.cpp b/src/boost/libs/flyweight/test/test_multictor_main.cpp
new file mode 100644
index 000000000..090aa3e6f
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_multictor_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of flyweight forwarding ctors.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_multictor.hpp"
+
+int main()
+{
+ test_multictor();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_no_locking.cpp b/src/boost/libs/flyweight/test/test_no_locking.cpp
new file mode 100644
index 000000000..a9b493c05
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_locking.cpp
@@ -0,0 +1,35 @@
+/* Boost.Flyweight test of no_locking.
+ *
+ * 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 "test_no_locking.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/hashed_factory.hpp>
+#include <boost/flyweight/no_locking.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct no_locking_flyweight_specifier
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T,no_locking> type;
+ };
+};
+
+void test_no_locking()
+{
+ test_basic_template<no_locking_flyweight_specifier>();
+}
diff --git a/src/boost/libs/flyweight/test/test_no_locking.hpp b/src/boost/libs/flyweight/test/test_no_locking.hpp
new file mode 100644
index 000000000..a18470da4
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_locking.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of no_locking.
+ *
+ * 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.
+ */
+
+void test_no_locking();
diff --git a/src/boost/libs/flyweight/test/test_no_locking_main.cpp b/src/boost/libs/flyweight/test/test_no_locking_main.cpp
new file mode 100644
index 000000000..85d2b090e
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_locking_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of no_locking.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_no_locking.hpp"
+
+int main()
+{
+ test_no_locking();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_no_tracking.cpp b/src/boost/libs/flyweight/test/test_no_tracking.cpp
new file mode 100644
index 000000000..876578173
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_tracking.cpp
@@ -0,0 +1,35 @@
+/* Boost.Flyweight test of no_tracking.
+ *
+ * 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 "test_no_tracking.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/hashed_factory.hpp>
+#include <boost/flyweight/no_tracking.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct no_tracking_flyweight_specifier
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T,no_tracking> type;
+ };
+};
+
+void test_no_tracking()
+{
+ test_basic_template<no_tracking_flyweight_specifier>();
+}
diff --git a/src/boost/libs/flyweight/test/test_no_tracking.hpp b/src/boost/libs/flyweight/test/test_no_tracking.hpp
new file mode 100644
index 000000000..99613731a
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_tracking.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of no_tracking.
+ *
+ * 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.
+ */
+
+void test_no_tracking();
diff --git a/src/boost/libs/flyweight/test/test_no_tracking_main.cpp b/src/boost/libs/flyweight/test/test_no_tracking_main.cpp
new file mode 100644
index 000000000..1cc9decd2
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_no_tracking_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of no_tracking.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_no_tracking.hpp"
+
+int main()
+{
+ test_no_tracking();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_serialization.cpp b/src/boost/libs/flyweight/test/test_serialization.cpp
new file mode 100644
index 000000000..cc348a238
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_serialization.cpp
@@ -0,0 +1,31 @@
+/* Boost.Flyweight test of serialization capabilities.
+ *
+ * Copyright 2006-2014 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 "test_serialization.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight.hpp>
+#include "test_serialization_template.hpp"
+
+using namespace boost::flyweights;
+
+struct serialization_flyweight_specifier
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T> type;
+ };
+};
+
+void test_serialization()
+{
+ test_serialization_template<serialization_flyweight_specifier>();
+}
diff --git a/src/boost/libs/flyweight/test/test_serialization.hpp b/src/boost/libs/flyweight/test/test_serialization.hpp
new file mode 100644
index 000000000..066f29ac8
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_serialization.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of serialization capabilities.
+ *
+ * Copyright 2006-2014 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.
+ */
+
+void test_serialization();
diff --git a/src/boost/libs/flyweight/test/test_serialization_main.cpp b/src/boost/libs/flyweight/test/test_serialization_main.cpp
new file mode 100644
index 000000000..d614e6b1d
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_serialization_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of serialization capabilities.
+ *
+ * Copyright 2006-2014 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/detail/lightweight_test.hpp>
+#include "test_serialization.hpp"
+
+int main()
+{
+ test_serialization();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/flyweight/test/test_serialization_template.hpp b/src/boost/libs/flyweight/test/test_serialization_template.hpp
new file mode 100644
index 000000000..767708187
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_serialization_template.hpp
@@ -0,0 +1,128 @@
+/* Boost.Flyweight test template for serialization capabilities.
+ *
+ * Copyright 2006-2014 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.
+ */
+
+#ifndef BOOST_FLYWEIGHT_TEST_SERIALIZATION_TEMPLATE_HPP
+#define BOOST_FLYWEIGHT_TEST_SERIALIZATION_TEMPLATE_HPP
+
+#if defined(_MSC_VER)&&(_MSC_VER>=1200)
+#pragma once
+#endif
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/flyweight/key_value.hpp>
+#include <boost/flyweight/serialize.hpp>
+#include <boost/functional/hash.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/serialization/vector.hpp>
+#include <string>
+#include <sstream>
+#include <vector>
+#include "heavy_objects.hpp"
+
+#define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
+
+struct tracked_string
+{
+ typedef tracked_string type;
+
+ tracked_string(){}
+ tracked_string(const char* str_):str(str_){}
+
+ const std::string& get()const{return str;}
+
+ friend bool operator==(const type& x,const type& y){return x.str==y.str;}
+ friend bool operator< (const type& x,const type& y){return x.str< y.str;}
+ friend bool operator!=(const type& x,const type& y){return x.str!=y.str;}
+ friend bool operator> (const type& x,const type& y){return x.str> y.str;}
+ friend bool operator>=(const type& x,const type& y){return x.str>=y.str;}
+ friend bool operator<=(const type& x,const type& y){return x.str<=y.str;}
+
+private:
+ friend class boost::serialization::access;
+
+ template<class Archive>
+ void serialize(Archive& ar,const unsigned int){ar&str;}
+
+ std::string str;
+};
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost{
+#endif
+
+inline std::size_t hash_value(const tracked_string& x)
+{
+ boost::hash<std::string> h;
+ return h(x.get());
+}
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+} /* namespace boost */
+#endif
+
+template<typename Flyweight,typename ForwardIterator>
+void test_serialization_template(
+ ForwardIterator first,ForwardIterator last
+ BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(Flyweight))
+{
+ std::vector<Flyweight> v1;
+ while(first!=last)v1.push_back(Flyweight(*first++));
+ std::ostringstream oss;
+ {
+ const std::vector<Flyweight>& crv1=v1;
+ boost::archive::text_oarchive oa(oss);
+ oa<<crv1;
+ }
+
+ std::vector<Flyweight> v2;
+ {
+ std::istringstream iss(oss.str());
+ boost::archive::text_iarchive ia(iss);
+ ia>>v2;
+ }
+
+ BOOST_TEST(v1==v2);
+}
+
+template<typename FlyweightSpecifier>
+void test_serialization_template(
+ BOOST_EXPLICIT_TEMPLATE_TYPE(FlyweightSpecifier))
+{
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,std::string
+ >::type string_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,tracked_string
+ >::type tracked_string_flyweight;
+
+ typedef typename boost::mpl::apply1<
+ FlyweightSpecifier,
+ boost::flyweights::key_value<std::string,texture,from_texture_to_string>
+ >::type texture_flyweight;
+
+ const char* words[]={"hello","boost","flyweight","boost","bye","c++","c++"};
+ test_serialization_template<string_flyweight>(
+ &words[0],&words[0]+LENGTHOF(words));
+ test_serialization_template<tracked_string_flyweight>(
+ &words[0],&words[0]+LENGTHOF(words));
+
+ const char* textures[]={
+ "wood","grass","sand","granite","terracotta","wood","sand","grass"};
+ test_serialization_template<texture_flyweight>(
+ &textures[0],&textures[0]+LENGTHOF(textures));
+}
+
+#undef LENGTHOF
+
+#endif
diff --git a/src/boost/libs/flyweight/test/test_set_factory.cpp b/src/boost/libs/flyweight/test/test_set_factory.cpp
new file mode 100644
index 000000000..06bf1493d
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_set_factory.cpp
@@ -0,0 +1,72 @@
+/* Boost.Flyweight test of set_factory.
+ *
+ * Copyright 2006-2013 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 "test_set_factory.hpp"
+
+#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
+#include <boost/flyweight/flyweight.hpp>
+#include <boost/flyweight/refcounted.hpp>
+#include <boost/flyweight/set_factory.hpp>
+#include <boost/flyweight/simple_locking.hpp>
+#include <boost/flyweight/static_holder.hpp>
+#include <functional>
+#include "test_basic_template.hpp"
+
+using namespace boost::flyweights;
+
+struct set_factory_flyweight_specifier1
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<T,set_factory<> > type;
+ };
+};
+
+struct set_factory_flyweight_specifier2
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ static_holder_class<boost::mpl::_1>,
+ set_factory_class<
+ boost::mpl::_1,boost::mpl::_2,
+ std::greater<boost::mpl::_2>,
+ std::allocator<boost::mpl::_1>
+ >
+ > type;
+ };
+};
+
+struct set_factory_flyweight_specifier3
+{
+ template<typename T>
+ struct apply
+ {
+ typedef flyweight<
+ T,
+ set_factory<
+ std::greater<boost::mpl::_2>,
+ std::allocator<boost::mpl::_1>
+ >,
+ static_holder_class<boost::mpl::_1>,
+ tag<char>
+ > type;
+ };
+};
+
+void test_set_factory()
+{
+ test_basic_template<set_factory_flyweight_specifier1>();
+ test_basic_template<set_factory_flyweight_specifier2>();
+ test_basic_template<set_factory_flyweight_specifier3>();
+}
diff --git a/src/boost/libs/flyweight/test/test_set_factory.hpp b/src/boost/libs/flyweight/test/test_set_factory.hpp
new file mode 100644
index 000000000..6e783e3a2
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_set_factory.hpp
@@ -0,0 +1,11 @@
+/* Boost.Flyweight test of set_factory.
+ *
+ * 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.
+ */
+
+void test_set_factory();
diff --git a/src/boost/libs/flyweight/test/test_set_factory_main.cpp b/src/boost/libs/flyweight/test/test_set_factory_main.cpp
new file mode 100644
index 000000000..c0e588515
--- /dev/null
+++ b/src/boost/libs/flyweight/test/test_set_factory_main.cpp
@@ -0,0 +1,18 @@
+/* Boost.Flyweight test of set_factory.
+ *
+ * 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 <boost/detail/lightweight_test.hpp>
+#include "test_set_factory.hpp"
+
+int main()
+{
+ test_set_factory();
+ return boost::report_errors();
+}