...one of the most highly
regarded and expertly designed C++ library projects in the
world.

— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards

`flyweight`

reference- Header
`"boost/flyweight/flyweight_fwd.hpp"`

synopsis - Header
`"boost/flyweight/flyweight.hpp"`

synopsis - Header
`"boost/flyweight/serialize.hpp"`

synopsis

`"boost/flyweight/flyweight_fwd.hpp"`

synopsis
#include <boost/functional/hash_fwd.hpp> #include <iosfwd> namespace boost{ namespace flyweights{ template< typename T, typename Arg1=implementation defined, typename Arg2=implementation defined, typename Arg3=implementation defined, typename Arg4=implementation defined, typename Arg5=implementation defined> class flyweight; // comparison: //OPis any of ==,<,!=,>,>=,<= template< typename T1,typename Arg11,...,typename Arg15, typename T2,typename Arg21,...,typename Arg25 > bool operator( const flyweight<T1,Arg11,...,Arg15>& x, const flyweight<T2,Arg21,...,Arg25>& y); template< typename T1,typename Arg11,...,typename Arg15, typename T2 > bool operatorOP(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y); template< typename T1, typename T2,typename Arg21,...,typename Arg25 > bool operatorOP(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y); // specialized algorithms: template<typename T,typename Arg1,...,typename Arg5> inline void swap( flyweight<T,Arg1,...,Arg5>& x,flyweight<T,Arg1,...,Arg5>& y); template< typename ElemType,typename Traits, typename T,typename Arg1,...,typename Arg5 > inline std::basic_ostream<ElemType,Traits>& operator<<( std::basic_ostream<ElemType,Traits>& out, const flyweight<T,Arg1,...,Arg5>& x); template< typename ElemType,typename Traits, typename T,typename Arg1,...,typename Arg5 > inline std::basic_istream<ElemType,Traits>& operator>>( std::basic_istream<ElemType,Traits>& in, flyweight<T,Arg1,...,Arg5>& x); } // namespace boost::flyweights using flyweights::flyweight; } // namespace boost // hash support: namespace std{ template<class T> struct hash; template<typename T,typename Arg1,...,typename Arg5> struct hash<boost::flyweight<T,Arg1,...,Arg5> >; } // namespace std namespace boost{ namespace flyweights{ template<typename T,typename Arg1,...,typename Arg5> inline std::size_t hash_value(const flyweight<T,Arg1,...,Arg5>& x); } // namespace boost::flyweights } // namespace boostOP

`flyweight_fwd.hpp`

forward declares the class template
`flyweight`

and its associated global functions and class template specializations.

`"boost/flyweight/flyweight.hpp"`

synopsis
`flyweight`

Objects of type `flyweight<...>`

provide access to immutable
values of type `flyweight<...>::value_type`

, with the following advantages over using
plain `value_type`

objects:

- Flyweight objects with equivalent value share the same representation
(the associated
`value_type`

object). - The size of flyweights is typically that of a pointer, which is in general
smaller than
`sizeof(value_type)`

.

`flyweight`

for `value_type`

results in a reduction in memory usage.
`flyweight`

is parameterized according to some aspects:

- Types
`key_value`

and`value_type`

(possibly equal), where`key_type`

serves as a key type to lookup and construct internal shared instances of objects of`value_type`

. - An optional tag type meant to syntactically differentiate between otherwise identical instantiations.
- The factory class used to store and retrieve the shared value objects.
- The type of holder used to
instantiate the flyweight factory and a mutex object, both of
which are unique to each specialization of the
`flyweight`

class template. - A locking policy determining the synchronization mechanisms for internal access to shared resources.
- A tracking policy which controls how values are treated when all their associated flyweight objects are destroyed.

`flyweight`

instantiation in the following manner:
- Each instantation of
`flyweight`

internally owns a unique factory object and a unique synchronization mutex object, both of which are created through the use of an associated holder type. - The flyweight factory stores elements of an undisclosed type
`Entry`

that is implicitly convertible to`const key_type&`

and also stores a subobject of`value_type`

. Every flyweight object is associated to a`value_type`

subobject of some`Entry`

stored in the factory. - The associated mutex object is used to protect all invocations to the insertion and deletion functions of the internal flyweight factory.
- Each flyweight object internally stores a value of some
undisclosed type
`Handle`

.`Handle`

and the`Entry`

type referred to above are obtained from invocations to the associated tracking policy, in the manner described for this concept.

`key_type`

equivalence
refers to the equivalence relationship induced by the factory class used.
Also, two values of `value_type`

are considered equivalent
if they are constructed from equivalent keys, or are copies of
objects constructed from equivalent keys.
#include <initializer_list> template< typename T, typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5 > class flyweight { public: typedefdependent on Tkey_type; typedefdependent on Tvalue_type; // static data initialization: static bool init(); class initializer{public:initializer();}; // construct/copy/destroy: flyweight(); template<typename... Args> explicit flyweight(Args&&... args); template<typename V> flyweight(std::initializer_list<V> list); flyweight(const flyweight& x); flyweight(flyweight& x); flyweight(const flyweight&& x); flyweight(flyweight&& x); explicit flyweight(const value_type& x); explicit flyweight(value_type& x); explicit flyweight(const value_type&& x); explicit flyweight(value_type&& x); template<typename V> flyweight& operator=(std::initializer_list<V> list); flyweight& operator=(const flyweight& x); flyweight& operator=(const value_type& x); flyweight& operator=(value_type&& x); // convertibility to underlying type: const key_type& get_key()const; const value_type& get()const; const value_type& operator*()const; operator const value_type&()const; const value_type* operator->()const; // modifiers: void swap(flyweight& x); };

`T`

can be either:

- An arbitrary type,
- a type of the form
`key_value<Key,Value[,KeyFromValue]>`

.

`key_type`

and `value_type`

are both equal to `T`

. In the second case, `key_type`

=`Key`

,
`value_type`

=`Value`

; we say then that the instantiation
of `flyweight`

is a `value_type`

is the type of the values flyweight objects give access to,
while value lookup is based on associated `key_type`

values.
`key_value`

must be
`Assignable`

and `value_type`

must be constructible from `key_type`

;
additionally, `key_value`

must
conform to any extra requirements imposed by the type of factory used.
For key-value flyweights, it is guaranteed that the creation or assignment of a flyweight
object results in at most one construction (or copy construction in some
particular cases) of an object
of `value_type`

, and this construction only occurs in the case that no
equivalent value existed previously in the flyweight factory.
The types `Arg1`

, ... , `Arg5`

, if provided, must be any
of the following, in no particular order:

- A tag,
- a factory specifier,
- a holder specifier,
- a locking policy,
- a tracking policy.

`flyweight`

instantiation is obtained through use of the
corresponding specifier; for instance, the factory results from a
certain (MPL) invocation of the given factory specifier, the internal
mutex from the given locking policy, etc.
The default configuration arguments are:
- No tagging,
`hashed_factory<>`

,`static_holder`

,`simple_locking`

,`refcounted`

tracking policy.

The static data internal to a given `flyweight`

instantiation
(factory instance, etc.) is constructed during the dynamic initialization
phase of the program and always before the first program-wide use of the
instantiated class. The following utilities can be
used when more control about the moment of construction is required.

`static bool init();`

Effects:After execution of this function the static data associated to the instantiation of`flyweight`

is guaranteed to be constructed.

Note:Concurrent execution of this function is not thread safe.

`initializer::initializer();`

Effects:Executes`init()`

.

`flyweight();`

Effects:Constructs a`flyweight`

object with the value`value_type(key_type())`

if`flyweight`

is key-value or`value_type()`

otherwise.

`template<typename... Args>`

explicit flyweight(Args&&... args);

Effects:Constructs a`flyweight`

object with the value`value_type(key_type(std::forward<Args>(args)...))`

if`flyweight`

is key-value or`value_type(std::forward<Args>(args)...)`

otherwise.

Note:In compilers without variadic template support, the implementation replaces this constructor with a number of overloads accepting any combination of const/non-const lvalue/rvalue reference arguments up to a maximum number that can be globally configured by the user.

`template<typename V>`

flyweight(std::initializer_list<V> list);

Effects:Constructs a`flyweight`

object with the value`value_type(key_type(list))`

if`flyweight`

is key-value or`value_type(list)`

otherwise.

Note:The specialization for a particular`std::initializer_list<V'>`

of this member function template is not available unless`key_type`

is constructible from`std::initializer_list<V'>`

.

`flyweight(const flyweight& x);`

flyweight(flyweight& x);

flyweight(const flyweight&& x);

flyweight(flyweight&& x);

Effects:Constructs a`flyweight`

object associated to the same value as`x`

.

Exception safety:`nothrow`

.

`explicit flyweight(const value_type& x);`

explicit flyweight(value_type& x);

explicit flyweight(const value_type&& x);

explicit flyweight(value_type&& x);

Requires:If`flyweight`

is key-value,`value_type`

is`Assignable`

and the`Key Extractor`

`KeyFromValue`

must have been supplied as part of the`key_value<>`

construct.

Effects:Constructs a`flyweight`

associated to a copy of`x`

or with a`value_type`

constructed from a key equivalent to that associated to`x`

. For non-key-value flyweights,`x`

is its own key; for key-value flyweights, the key is extracted through use of an object of type`KeyFromValue`

.

`template<typename V>`

flyweight& operator=(std::initializer_list<V> list);

Effects:`*this=flyweight(list)`

.

Returns:`*this`

.

Note:The specialization for a particular`std::initializer_list<V'>`

of this member function template is not available unless`key_type`

is constructible from`std::initializer_list<V'>`

.

`flyweight& operator=(const flyweight& x);`

Effects:Associates the`flyweight`

object with the same value as`x`

.

Returns:`*this`

.

Exception safety:`nothrow`

.

`flyweight& operator=(const value_type& x);`

flyweight& operator=(value_type&& x);

Effects:`*this=flyweight(x)`

(first overload),`*this=flyweight(std::move(x))`

(second overload).

Returns:`*this`

.

`const key_type& get_key()const;`

Returns:A copy of the key used to construct the`value_type`

associated to the`flyweight`

object.

Exception safety:If`flyweight`

is not key-value or if`KeyFromValue`

was not provided,`nothrow`

.

`const value_type& get()const;`

const value_type& operator*()const;

operator const value_type&()const;

Returns:The value associated to the`flyweight`

object.

Exception safety:`nothrow`

.

`const value_type* operator->()const`

Returns:The address of the value associated to the`flyweight`

object.

Exception safety:`nothrow`

.

`void swap(flyweight& x);`

Effects:Swaps the associations to`value_type`

s each flyweight object has. No swapping of`key_type`

or`value_type`

objects is done.

Exception safety:`nothrow`

.

`template<`

typename T1,typename Arg11,...,typename Arg15,

typename T2,typename Arg21,...,typename Arg25

>

bool operator ==(

const flyweight<T1,Arg11,...,Arg15>& x,

const flyweight<T2,Arg21,...,Arg25>& y);

Returns:If`x`

and`y`

are of the same type, returns`true`

if and only if they are associated to the same value; if`x`

and`y`

have different types, returns`x.get()==y.get()`

.

Exception safety:If`x`

and`y`

are of the same type,`nothrow`

.

`template<`

typename T1,typename Arg11,...,typename Arg15,

typename T2

>

bool operator ==(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y);

Returns:`x.get()==y`

.

`template<`

typename T1,

typename T2,typename Arg21,...,typename Arg25

>

bool operator ==(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y);

Returns:`x==y.get()`

.

`template<`

typename T1,typename Arg11,...,typename Arg15,

typename T2,typename Arg21,...,typename Arg25

>

bool operator <(

const flyweight<T1,Arg11,...,Arg15>& x,

const flyweight<T2,Arg21,...,Arg25>& y);

Returns:`x.get()<y.get()`

.

`template<`

typename T1,typename Arg11,...,typename Arg15,

typename T2

>

bool operator <(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y);

Returns:`x.get()<y`

.

`template<`

typename T1,

typename T2,typename Arg21,...,typename Arg25

>

bool operator <(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y);

Returns:`x<y.get()`

.

`template<`

typename T1,typename Arg11,...,typename Arg15,

typename T2,typename Arg21,...,typename Arg25

>

bool operator *OP*(

const flyweight<T1,Arg11,...,Arg15>& x,

const flyweight<T2,Arg21,...,Arg25>& y);

template<

typename T1,typename Arg11,...,typename Arg15,

typename T2

>

bool operator *OP*(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y);

template<

typename T1,

typename T2,typename Arg21,...,typename Arg25

>

bool operator *OP*(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y);

(

is any of *OP*`!=`

, `>`

,
`>=`

, `<=`

.)

Returns:`true`

if and only if`!(x==y)`

(`is`

OP`!=`

),

`y< x`

(`is`

OP`>`

),

`!(x< y)`

(`is`

OP`>=`

),

`!(y< x)`

(`is`

OP`<=`

).

`template<typename T,typename Arg1,...,typename Arg5>`

inline void swap(

flyweight<T,Arg1,...,Arg5>& x,flyweight<T,Arg1,...,Arg5>& y);

Effects:`x.swap(y)`

.

`template<`

typename ElemType,typename Traits,

typename T,typename Arg1,...,typename Arg5

>

inline std::basic_ostream<ElemType,Traits>& operator<<(

std::basic_ostream<ElemType,Traits>& out,

const flyweight<T,Arg1,...,Arg5>& x);

Effects:`out<<x.get()`

.

Returns:`out`

.

`template<`

typename ElemType,typename Traits,

typename T,typename Arg1,...,typename Arg5

>

inline std::basic_istream<ElemType,Traits>& operator>>(

std::basic_istream<ElemType,Traits>& in,

flyweight<T,Arg1,...,Arg5>& x);

Requires:If`flyweight`

is key-value,`value_type`

is`Assignable`

and the`Key Extractor`

`KeyFromValue`

must have been supplied as part of the`key_value<>`

construct.

Effects:Reads an object of type`value_type`

from`in`

and assigns it to`x`

.

Returns:`in`

.

Support is provided for hashing `flyweight`

s both with `std::hash`

and
`boost::hash`

. In either case, the calculation
does not involve hashing the associated `value_type`

objects themselves; so, it is
immaterial whether `value_type`

is hashable or not.
The results given by `std::hash`

and `boost::hash`

for the same
`flyweight`

object will usually differ.

**Note:** Hash support can be disabled to solve
clashes with code where this has already been defined by the user.

`namespace std{`

template<typename T,typename Arg1,...,typename Arg5>

struct hash<boost::flyweight<T,Arg1,...,Arg5> >;

}

This template specialization meets the requirements of class template`std::hash`

in[unord.hash]. No exception is thrown when invoking instances of this specialization.

`template<typename T,typename Arg1,...,typename Arg5>`

inline std::size_t hash_value(const flyweight<T,Arg1,...,Arg5>& x);

Returns:A hash value for`x`

to be used by Boost.Hash.

Exception safety:`nothrow`

.

`BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS`

```
In compilers without variadic template support,
globally define this macro to set the maximum number of
arguments accepted by
````flyweight`

forwarding constructor, which by default
is 5.

`BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT`

```
If defined, hash support is not provided. This can be useful to cope
with legacy code where general
````flyweight`

hashing has already been
defined by the user.

`"boost/flyweight/serialize.hpp"`

synopsis
`serialize.hpp`

includes the necessary functionality for interoperability
of `flyweight`

with
Boost.Serialization.

`flyweight`

s can be archived and retrieved by means of
Boost.Serialization. Regular as well
as XML archives are supported.
Serialization is done in an efficient manner so that saving equivalent `flyweight`

s
result in their common `key_type`

value being stored only once, regardless
of whether `key_type`

is
tracked by
Boost.Serialization or not.

`flyweight`

object `x`

to an
output archive (XML archive) `ar`

.
Operation: loading of aRequires:`key_type`

is serializable (XML-serializable).

Effects:The value`k=x.get_key()`

is saved into`ar`

as part of this operation or of a previous saving operation of a`flyweight`

object with the same key.

Exception safety:Strong with respect to`x`

. If an exception is thrown,`ar`

may be left in an inconsistent state.

`flyweight`

`x'`

from an
input archive (XML archive) `ar`

.
Requires:`key_type`

is serializable (XML-serializable).

Effects:`x'`

is associated to a value constructed from a key equivalent to`k'`

, a restored copy of the value`k`

defined above.

Exception safety:Strong with respect to`x'`

. If an exception is thrown,`ar`

may be left in an inconsistent state.

Revised March 17th 2023

© Copyright 2006-2023 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)