mirror of
https://github.com/boostorg/flyweight.git
synced 2026-01-19 04:12:09 +00:00
added serialization capabilities
This commit is contained in:
@@ -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>© Copyright 2006-2009 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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<T></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<flyweight<std::string> ></code>
|
||||
and save the structure to a serialization file.
|
||||
</li>
|
||||
<li>Load a <code>std::vector<flyweight<std::string> ></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>© Copyright 2006-2008 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>© Copyright 2006-2009 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>© Copyright 2006-2014 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -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>© Copyright 2006-2014 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -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>© Copyright 2006-2014 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -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>© Copyright 2006-2014 Joaquín M López Muñoz.
|
||||
Distributed under the Boost Software
|
||||
|
||||
@@ -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<T></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"><</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">></span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Archive</span><span class="special">></span>
|
||||
<span class="keyword">void</span> <span class="identifier">serialize</span><span class="special">(</span><span class="identifier">Archive</span><span class="special">&</span> <span class="identifier">ar</span><span class="special">,</span><span class="identifier">user_entry</span><span class="special">&</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">&</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">&</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">&</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>© Copyright 2006-2008 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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>© Copyright 2006-2008 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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<key_value<K,T> ></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>© Copyright 2006-2009 Joaquín M López Muñoz.
|
||||
<p>© Copyright 2006-2014 Joaquín M López Muñ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">
|
||||
|
||||
@@ -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
133
example/serialization.cpp
Normal 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;
|
||||
}
|
||||
79
include/boost/flyweight/detail/archive_constructed.hpp
Normal file
79
include/boost/flyweight/detail/archive_constructed.hpp
Normal 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
|
||||
99
include/boost/flyweight/detail/serialization_helper.hpp
Normal file
99
include/boost/flyweight/detail/serialization_helper.hpp
Normal 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
|
||||
98
include/boost/flyweight/serialize.hpp
Normal file
98
include/boost/flyweight/serialize.hpp
Normal 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
|
||||
@@ -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 ]
|
||||
;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
31
test/test_serialization.cpp
Normal file
31
test/test_serialization.cpp
Normal 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>();
|
||||
}
|
||||
11
test/test_serialization.hpp
Normal file
11
test/test_serialization.hpp
Normal 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();
|
||||
18
test/test_serialization_main.cpp
Normal file
18
test/test_serialization_main.cpp
Normal 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();
|
||||
}
|
||||
128
test/test_serialization_template.hpp
Normal file
128
test/test_serialization_template.hpp
Normal 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
|
||||
Reference in New Issue
Block a user