added serialization capabilities

This commit is contained in:
joaquintides
2014-09-01 17:24:12 +02:00
parent a9b367a0ed
commit 6b26fc69ec
21 changed files with 790 additions and 27 deletions

View File

@@ -72,6 +72,16 @@ and to Peter Dimov for kindly extending the interface of his
implementation of the fix.
</p>
<h2><a name="boost_1_57">Boost 1.57 release</a></h2>
<p>
Boost.Flyweight serialization uses the newly introduced
<a href="../../serialization/doc/special.html#helpersupport">helper support
functionality</a> of the <a href="../../serialization/index.html">Boost Serialization Library</a>
from Robert Ramey. Without helper support, serialization of <code>flyweight</code>s would have
been unacceptably costly in terms of archive space consumption.
</p>
<hr>
<div class="prev_link"><a href="release_notes.html"><img src="prev.gif" alt="release notes" border="0"><br>
@@ -85,9 +95,9 @@ Index
<br>
<p>Revised April 25th 2009</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -36,8 +36,9 @@ Tests
<li><a href="#example3">Example 3: flyweights and the composite pattern</a></li>
<li><a href="#example4">Example 4: formatted text processing</a></li>
<li><a href="#example5">Example 5: flyweight-based memoization</a></li>
<li><a href="#example6">Example 6: performance comparison</a></li>
<li><a href="#example7">Example 7: custom factory</a></li>
<li><a href="#example6">Example 6: serialization</a></li>
<li><a href="#example7">Example 7: performance comparison</a></li>
<li><a href="#example8">Example 8: custom factory</a></li>
</ul>
<h2><a name="example1">Example 1: basic usage</a></h2>
@@ -200,7 +201,33 @@ policy is used so that the memoized computations persist for future
use throughout the program. The provided program develops this example in full.
</p>
<h2><a name="example6">Example 6: performance comparison</a></h2>
<h2><a name="example6">Example 6: serialization</a></h2>
<p>
See <a href="../example/serialization.cpp">source code</a>.
</p>
<p>
If <code>T</code> is serializable (using
<a href="../../serialization/index.html">Boost.Serialization</a>),
<code>flyweight&lt;T&gt;</code> is automatically
serializable as well. The example program performs the following two
complementary procedures:
<ul>
<li>Read a text file as a <code>std::vector&lt;flyweight&lt;std::string&gt; &gt;</code>
and save the structure to a serialization file.
</li>
<li>Load a <code>std::vector&lt;flyweight&lt;std::string&gt; &gt;</code> from a
serialization file and write it as a text file.
</li>
</ul>
If you visually inspect the contents of any of the generated serialization files
you can notice that no word appears twice; Boost.Flyweight implements some internal
machinery that avoids duplicating output information when saving equal
<code>flyweight</code> objects.
</p>
<h2><a name="example7">Example 7: performance comparison</a></h2>
<p>
See <a href="../example/perf.cpp">source code</a>.
@@ -218,7 +245,7 @@ The program has been used to produce the experimental results given
at the <a href="performance.html#results">performance section</a>.
</p>
<h2><a name="example7">Example 7: custom factory</a></h2>
<h2><a name="example8">Example 8: custom factory</a></h2>
<p>
See <a href="../example/custom_factory.cpp">source code</a>.
@@ -245,9 +272,9 @@ Tests
<br>
<p>Revised December 2nd 2008</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -300,7 +300,7 @@ into the processor cache.
<h2><a name="results">Experimental results</a></h2>
<p>
A <a href="examples.html#example6">profiling program</a> was devised to test
A <a href="examples.html#example7">profiling program</a> was devised to test
the space and time efficiency of different instantiations of <code>flyweight</code>
against a base situation not using Boost.Flyweight. The profiled scenarios are:
<ol>
@@ -459,9 +459,9 @@ Examples
<br>
<p>Revised June 22nd 2009</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -50,6 +50,12 @@ Key-value flyweights
</li>
</ul>
</li>
<li><a href="#serialize_synopsis">Header
<code>"boost/flyweight/serialize.hpp"</code> synopsis</a>
<ul>
<li><a href="#serialization">Serialization</a></li>
</ul>
</li>
</ul>
<h2>
@@ -641,6 +647,55 @@ arguments accepted by <code>flyweight</code>
is 5.
</blockquote>
<h2>
<a name="serialize_synopsis">Header
</a><a href="../../../../boost/flyweight/serialize.hpp"><code>"boost/flyweight/serialize.hpp"</code></a>
synopsis
</h2>
<p>
<code>serialize.hpp</code> includes the necessary functionality for interoperability
of <code>flyweight</code> with
<a href="../../../serialization/index.html">Boost.Serialization</a>.
</p>
<h3><a name="serialization">Serialization</a></h3>
<p>
<code>flyweight</code>s can be archived and retrieved by means of
<a href="../../../serialization/index.html">Boost.Serialization</a>. Regular as well
as XML archives are supported.
Serialization is done in an efficient manner so that saving equivalent <code>flyweight</code>s
result in their common <code>key_type</code> value being stored only once, regardless
of whether <code>key_type</code> is
<a href="../../../serialization/doc/traits.html#tracking">tracked</a> by
Boost.Serialization or not.
</p>
Operation: saving of a <code>flyweight</code> object <code>x</code> to an
output archive (XML archive) <code>ar</code>.
<blockquote>
<b>Requires:</b> <code>key_type</code> is serializable (XML-serializable).<br>
<b>Effects:</b> The value <code>k=x.get_key()</code> is saved into <code>ar</code> as
part of this operation or of a previous saving operation of a <code>flyweight</code>
object with the same key.<br>
<b>Exception safety:</b> Strong with respect to <code>x</code>. If an exception
is thrown, <code>ar</code> may be left in an inconsistent state.
</blockquote>
Operation: loading of a <code>flyweight</code> <code>x'</code> from an
input archive (XML archive) <code>ar</code>.
<blockquote>
<b>Requires:</b> <code>key_type</code> is serializable (XML-serializable).<br>
<b>Effects:</b> <code>x'</code> is associated to a value constructed from a key
equivalent to <code>k'</code>, a restored copy of the value <code>k</code>
defined above.<br>
<b>Exception safety:</b> Strong with respect to <code>x'</code>. If an exception
is thrown, <code>ar</code> may be left in an inconsistent state.
</blockquote>
<hr>
<div class="prev_link"><a href="index.html"><img src="../prev.gif" alt="Boost.Flyweight reference" border="0"><br>
@@ -655,7 +710,7 @@ Key-value flyweights
<br>
<p>Revised February 1st 2014</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@@ -53,6 +53,7 @@ Boost.Flyweight comprises the following public headers:
<ul>
<li><a href="flyweight.html#flyweight_fwd_synopsis"><code>"boost/flyweight/flyweight_fwd.hpp"</code></a></li>
<li><a href="flyweight.html#synopsis"><code>"boost/flyweight/flyweight.hpp"</code></a></li>
<li><a href="flyweight.html#serialize_synopsis"><code>"boost/flyweight/flyweight_serialize.hpp"</code></a></li>
</ul>
</li>
<li>Key-value flyweights
@@ -110,7 +111,9 @@ Boost.Flyweight comprises the following public headers:
<h2><a name="dependencies">Dependencies</a></h2>
<p>
Boost.Flyweight is a header-only library, requiring no additional
In order to use the serialization capabilities of Boost.Flyweight,
the appropriate Boost.Serialization library module must be linked. Other
than that, Boost.Flyweight is a header-only library, requiring no additional
object modules. The default <a href="locking.html#simple_locking"><code>simple_locking</code></a>
locking policy introduces a dependency on the Pthreads library on those POSIX-compliant
environments where the <a href="../../../config/doc/html/index.html">Boost.Config</a> macro
@@ -151,7 +154,7 @@ Index
<br>
<p>Revised April 4th 2014</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@@ -31,6 +31,7 @@ Acknowledgements
<h2>Contents</h2>
<ul>
<li><a href="#boost_1_57">Boost 1.57 release</a></li>
<li><a href="#boost_1_56">Boost 1.56 release</a></li>
<li><a href="#boost_1_55">Boost 1.55 release</a></li>
<li><a href="#boost_1_45">Boost 1.45 release</a></li>
@@ -40,6 +41,16 @@ Acknowledgements
<li><a href="#boost_1_38">Boost 1.38 release</a></li>
</ul>
<h2><a name="boost_1_57">Boost 1.57 release</a></h2>
<p>
<ul>
<li>Added serialization support via
<a href="../../serialization/index.html">Boost Serialization</a>.
</li>
</ul>
</p>
<h2><a name="boost_1_56">Boost 1.56 release</a></h2>
<p>
@@ -130,7 +141,7 @@ Acknowledgements
<br>
<p>Revised February 1st 2014</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@@ -79,6 +79,11 @@ of Boost.Flyweight.
<td><a href="tutorial/configuration.html#no_tracking"><code>no_tracking</code></a> policy.</td>
</tr>
<tr>
<td><a href="../test/test_serialization.cpp"><code>test_serialization.cpp</code></a></td>
<td>Exercises <code>flyweight</code> <a href="tutorial/basics.html#serialization">serialization
capabilities</a>.</td>
</tr>
<tr class="odd_tr">
<td><a href="../test/test_set_factory.cpp"><code>test_set_factory.cpp</code></a></td>
<td><a href="tutorial/configuration.html#set_factory"><code>set_factory</code></a>
factory specifier.</td>
@@ -101,7 +106,7 @@ Future work
<br>
<p>Revised February 1st 2014</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software

View File

@@ -30,7 +30,11 @@ Key-value flyweights
<h2>Contents</h2>
<ul>
<li><a href="#intro">Introduction</a></li>
<li><a href="#intro">Introduction</a>
<ul>
<li><a href="#serialization">Serialization</a></li>
</ul>
</li>
<li><a href="#requirements">Flyweight requirements</a></li>
</ul>
@@ -172,6 +176,45 @@ The <a href="../examples.html">examples section</a> explores
some common usage scenarios of Boost.Flyweight.
</p>
<h4><a name="serialization">Serialization</a></h4>
<p>
<code>flyweight&lt;T&gt;</code> can be serialized by means of the
<a href="../../../serialization/index.html">Boost Serialization Library</a>
as long as the underlying <code>T</code> is serializable. Both regular and
XML archives are supported. In order to
use Boost.Flyweight serialization capabilities, the specific
header <a href="../reference/flyweight.html#serialize_synopsis"><code>"boost/flyweight/serialize.hpp"</code></a>
must be included.
</p>
<blockquote><pre><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">flyweight</span><span class="special">/</span><span class="identifier">serialize</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Archive</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">serialize</span><span class="special">(</span><span class="identifier">Archive</span><span class="special">&amp;</span> <span class="identifier">ar</span><span class="special">,</span><span class="identifier">user_entry</span><span class="special">&amp;</span> <span class="identifier">user</span><span class="special">,</span><span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">first_name</span><span class="special">;</span>
<span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">last_name</span><span class="special">;</span>
<span class="identifier">ar</span><span class="special">&amp;</span><span class="identifier">user</span><span class="special">.</span><span class="identifier">age</span><span class="special">;</span>
<span class="special">...</span>
<span class="special">}</span>
</pre></blockquote>
<p>
Much as using Boost.Flyweight reduces memory consumption due to the internal
sharing of duplicate values, serializing <code>flyweight</code>s can also
result in smaller archive files, as a common value is only stored
once and their associated <code>flyweight</code>s get saved as references to it.
This policy is observed even if <code>flyweight</code> underlying type is
not <a href="../../../serialization/doc/traits.html#tracking">tracked</a>
by Boost.Serialization.
</p>
<p>
See <a href="../examples.html#example6">example 6</a> at the examples section
for an illustration of use of Boost.Flyweight serialization capabilities.
</p>
<h3><a name="requirements">Flyweight requirements</a></h3>
<p>
@@ -214,9 +257,9 @@ Key-value flyweights
<br>
<p>Revised December 2nd 2008</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -270,7 +270,7 @@ to do this tagging:
</p>
<p>
<a href="../examples.html#example7">Example 7</a> in the examples section develops
<a href="../examples.html#example8">Example 8</a> in the examples section develops
in full the <code>verbose_factory_class</code> case sketched above.
</p>
@@ -549,9 +549,9 @@ Technical issues
<br>
<p>Revised December 2nd 2008</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2008 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -202,6 +202,8 @@ by the user. The only requisite retained on <code>T</code> is that it must be
constructible from <code>K</code>; only in the case that a flyweight is directly
assigned a <code>T</code> object is also <code>T</code> required to be
<a href="http://www.sgi.com/tech/stl/Assignable.html"><code>Assignable</code></a>.
To serialize objects of type <code>flyweight&lt;key_value&lt;K,T&gt; &gt;</code>
only <code>K</code> needs to be serializable.
</p>
<hr>
@@ -218,9 +220,9 @@ Configuring Boost.Flyweight
<br>
<p>Revised February 21st 2009</p>
<p>Revised September 1st 2014</p>
<p>&copy; Copyright 2006-2009 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
<p>&copy; Copyright 2006-2014 Joaqu&iacute;n M L&oacute;pez Mu&ntilde;oz.
Distributed under the Boost Software
License, Version 1.0. (See accompanying file <a href="../../../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">

View File

@@ -1,6 +1,6 @@
# Boost.Flyweight examples Jamfile
#
# Copyright 2006-2008 Joaquín M López Muñoz.
# 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)
@@ -47,3 +47,9 @@ exe perf
: <include>$(BOOST_ROOT)
: release
;
exe serialization
: serialization.cpp
/boost/serialization//boost_serialization/<link>static
: <include>$(BOOST_ROOT)
;

133
example/serialization.cpp Normal file
View File

@@ -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;
}

View File

@@ -0,0 +1,79 @@
/* 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_DETAIL_ARCHIVE_CONSTRUCTED_HPP
#define BOOST_FLYWEIGHT_DETAIL_ARCHIVE_CONSTRUCTED_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/detail/no_exceptions_support.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>
namespace boost{
namespace flyweights{
namespace detail{
/* constructs a stack-based object from a serialization archive */
template<typename T>
struct archive_constructed:private noncopyable
{
template<class Archive>
archive_constructed(Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>get();
}
BOOST_CATCH(...){
(&get())->~T();
BOOST_RETHROW;
}
BOOST_CATCH_END
}
template<class Archive>
archive_constructed(const char* name,Archive& ar,const unsigned int version)
{
serialization::load_construct_data_adl(ar,&get(),version);
BOOST_TRY{
ar>>serialization::make_nvp(name,get());
}
BOOST_CATCH(...){
(&get())->~T();
BOOST_RETHROW;
}
BOOST_CATCH_END
}
~archive_constructed()
{
(&get())->~T();
}
T& get(){return *static_cast<T*>(static_cast<void*>(&space));}
private:
typename aligned_storage<sizeof(T),alignment_of<T>::value>::type space;
};
} /* namespace flyweights::detail */
} /* namespace flyweights */
} /* namespace boost */
#endif

View File

@@ -0,0 +1,99 @@
/* 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_DETAIL_SERIALIZATION_HELPER_HPP
#define BOOST_FLYWEIGHT_DETAIL_SERIALIZATION_HELPER_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/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/noncopyable.hpp>
#include <boost/serialization/extended_type_info.hpp>
#include <vector>
namespace boost{
namespace flyweights{
namespace detail{
/* The serialization helpers for flyweight<T> map numerical IDs to
* flyweight exemplars --an exemplar is the flyweight object
* associated to a given value that appears first on the serialization
* stream, so that subsequent equivalent flyweight objects will be made
* to refer to it during the serialization process.
*/
template<typename Flyweight>
struct flyweight_value_address
{
typedef const typename Flyweight::value_type* result_type;
result_type operator()(const Flyweight& x)const{return &x.get();}
};
template<typename Flyweight>
class save_helper:private noncopyable
{
typedef multi_index::multi_index_container<
Flyweight,
multi_index::indexed_by<
multi_index::random_access<>,
multi_index::hashed_unique<flyweight_value_address<Flyweight> >
>
> table;
public:
typedef typename table::size_type size_type;
size_type size()const{return t.size();}
size_type find(const Flyweight& x)const
{
return multi_index::project<0>(t,multi_index::get<1>(t).find(&x.get()))
-t.begin();
}
void push_back(const Flyweight& x){t.push_back(x);}
private:
table t;
};
template<typename Flyweight>
class load_helper:private noncopyable
{
typedef std::vector<Flyweight> table;
public:
typedef typename table::size_type size_type;
size_type size()const{return t.size();}
Flyweight operator[](size_type n)const{return t[n];}
void push_back(const Flyweight& x){t.push_back(x);}
private:
table t;
};
} /* namespace flyweights::detail */
} /* namespace flyweights */
} /* namespace boost */
#endif

View File

@@ -0,0 +1,98 @@
/* 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_SERIALIZE_HPP
#define BOOST_FLYWEIGHT_SERIALIZE_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/flyweight/flyweight_fwd.hpp>
#include <boost/flyweight/detail/archive_constructed.hpp>
#include <boost/flyweight/detail/serialization_helper.hpp>
#include <boost/serialization/nvp.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/throw_exception.hpp>
#include <memory>
/* Serialization routines for flyweight<T>.
*/
namespace boost{
namespace serialization{
template<
class Archive,
typename T,typename Arg1,typename Arg2,typename Arg3
>
inline void serialize(
Archive& ar,::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f,
const unsigned int version)
{
split_free(ar,f,version);
}
template<
class Archive,
typename T,typename Arg1,typename Arg2,typename Arg3
>
void save(
Archive& ar,const ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f,
const unsigned int version)
{
typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight;
typedef ::boost::flyweights::detail::save_helper<flyweight> helper;
typedef typename helper::size_type size_type;
helper& hlp=ar.template get_helper<helper>();
size_type n=hlp.find(f);
ar<<make_nvp("item",n);
if(n==hlp.size()){
ar<<make_nvp("key",f.get_key());
hlp.push_back(f);
}
}
template<
class Archive,
typename T,typename Arg1,typename Arg2,typename Arg3
>
void load(
Archive& ar,::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3>& f,
const unsigned int version)
{
typedef ::boost::flyweights::flyweight<T,Arg1,Arg2,Arg3> flyweight;
typedef typename flyweight::key_type key_type;
typedef ::boost::flyweights::detail::load_helper<flyweight> helper;
typedef typename helper::size_type size_type;
helper& hlp=ar.template get_helper<helper>();
size_type n=0;
ar>>make_nvp("item",n);
if(n>hlp.size()){
throw_exception(
archive::archive_exception(archive::archive_exception::other_exception));
}
else if(n==hlp.size()){
::boost::flyweights::detail::archive_constructed<key_type> k(
"key",ar,version);
hlp.push_back(flyweight(k.get()));
}
f=hlp[n];
}
} /* namespace serialization */
} /* namespace boost */
#endif

View File

@@ -1,6 +1,6 @@
# Boost.Flyweight tests Jamfile
#
# Copyright 2006-2008 Joaquín M López Muñoz.
# 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)
@@ -26,6 +26,8 @@ test-suite "flyweight" :
[ 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 ]
;

View File

@@ -1,6 +1,6 @@
/* Boost.Flyweight test suite.
*
* Copyright 2006-2008 Joaquin M Lopez Munoz.
* 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)
@@ -18,6 +18,7 @@
#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()
@@ -30,6 +31,7 @@ int main()
test_multictor();
test_no_locking();
test_no_tracking();
test_serialization();
test_set_factory();
return boost::report_errors();

View File

@@ -0,0 +1,31 @@
/* Boost.Flyweight 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>();
}

View File

@@ -0,0 +1,11 @@
/* Boost.Flyweight 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();

View File

@@ -0,0 +1,18 @@
/* Boost.Flyweight 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();
}

View File

@@ -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