# Boost.Flyweight `flyweight` reference

Boost.Flyweight reference
Boost.Flyweight reference
Key-value flyweights

## Contents

- Header `"boost/flyweight/flyweight_fwd.hpp"` synopsis
- Header `"boost/flyweight/flyweight.hpp"` synopsis
  - Class template `flyweight`
    - Instantiation types
    - Static data initialization
    - Constructors, copy and assignment
    - Convertibility to the underlying types
    - Modifiers
    - Comparison operators
    - Specialized algorithms
    - Configuration macros

## Header `"boost/flyweight/flyweight_fwd.hpp"` synopsis

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

>     // OP is any of ==,<,!=,>,>=,<=

>     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);

>     // 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_ostream<ElemType,Traits>& operator>>(
>       std::basic_istream<ElemType,Traits>& in,
>       flyweight<T,Arg1,...,Arg5>& x);

>     } // namespace boost::flyweights

>     using flyweights::flyweight;

>     } // namespace boost

`flyweight_fwd.hpp` forward declares the class template `flyweight` and its associated global functions.

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

### Class template `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)`.

So, if the level of redundancy (ratio of total objects to different values) is high enough, substituting a suitable instantiation of `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.

These aspects impact the internal structure and behavior of the `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.

In what follows, we implicitly assume that `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.

>     template<
>       typename T,
>       typename Arg1,typename Arg2,typename Arg3,typename Arg4,typename Arg5
>     >
>     class flyweight
>     {
>     public:
>       typedef dependent on T key_type;
>       typedef dependent on T value_type;

>       // static data initialization:

>       static bool init();
>       class initializer{public:initializer();};

>       // construct/copy/destroy:

>       flyweight();
>       flyweight(const flyweight& x);
>       flyweight(flyweight& x);

>       // forwarding constructors:
>       // n is implementation defined. All combinations of constant
>       // and non constant reference arguments are provided.

>       template<typename T0>
>       explicit flyweight([const] T0& t0);
>       template<typename T0,typename T1>
>       flyweight([const] T0& t0,[const] T1& t1);
>       ...
>       template<typename T0,...,typename Tn-1>
>       flyweight([const] T0& t0,...,[const] Tn-1& tn-1);

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

>       // convertibility to underlying type:

>       const key_type&   get_key()const;
>       const value_type& get()const;
>       operator const    value_type&()const;

>       // modifiers:

>       void swap(flyweight& x);
>     };

#### Instantiation types

`T` can be either:

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

In the first case, the nested types `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 key-value flyweight. `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.

No aspect can be specified twice. Each internal component of the `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.

#### Static data initialization

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()`.

#### Constructors, copy and assignment

`flyweight();`

> Requires: `key_type` is `Default Constructible`.
> Effects: Constructs a `flyweight` object associated with value `value_type(key_type())`.

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

> Effects: Constructs a `flyweight` object with value `x.get()`.
> Exception safety: `nothrow`.

`template<typename T0>
explicit flyweight([const] T0& t0);
template<typename T0,typename T1>
flyweight([const] T0& t0,[const] T1& t1);
...
template<typename T0,...,typename Tn-1>
flyweight([const] T0& t0,...,[const] Tn-1& tn-1);`

> Effects: Constructs a `flyweight` object with value `value_type(key_type(t0,...,ti))`, up to an implementation defined number of arguments.
> Note: In this implementation, the maximum number of arguments can be globally configured by the user.

`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);`

> 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: Associates the `flyweight` object with 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`.
> Returns: `*this`.

#### Convertibility to the underlying types

`const key_type& get_key()const;`

> Return: 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;
operator const value_type&()const;`

> Return: The value associated to the `flyweight` object.
> Exception safety: `nothrow`.

#### Modifiers

`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`.

#### Comparison operators

`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);`

(`OP` is any of `!=`, `>`, `>=`, `<=`.)

> Returns: `true` if and only if

> > `!(x==y)` (`OP` is `!=`),
> > `y< x` (`OP` is `>` ),
> > `!(x< y)` (`OP` is `>=`),
> > `!(y< x)` (`OP` is `<=`).

#### Specialized algorithms

`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_ostream<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`.

#### Configuration macros

`BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS`

> Effects: Globally define this macro to set the maximum number of arguments accepted by `flyweight` forwarding constructors, which by default is 5.

Boost.Flyweight reference
Boost.Flyweight reference
Key-value flyweights

Revised December 2nd 2008

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