Boost.Flyweight Documentation - Factories reference

# Boost.Flyweight Factories reference

Tags
Boost.Flyweight reference
Holders

## Contents

- Factories and factory specifiers
- Header `"boost/flyweight/factory_tag.hpp"` synopsis
  - Class template `is_factory`
  - Class template `factory`
- Header `"boost/flyweight/hashed_factory_fwd.hpp"` synopsis
- Header `"boost/flyweight/hashed_factory.hpp"` synopsis
  - Class template `hashed_factory_class`
  - Class template `hashed_factory`
- Header `"boost/flyweight/concurrent_factory_fwd.hpp"` synopsis
- Header `"boost/flyweight/concurrent_factory.hpp"` synopsis
  - Class template `concurrent_factory_class`
  - Class template `concurrent_factory`
- Header `"boost/flyweight/set_factory_fwd.hpp"` synopsis
- Header `"boost/flyweight/set_factory.hpp"` synopsis
  - Class template `set_factory_class`
  - Class template `set_factory`
- Header `"boost/flyweight/assoc_container_factory_fwd.hpp"` synopsis
- Header `"boost/flyweight/assoc_container_factory.hpp"` synopsis
  - Class template `assoc_container_factory_class`
  - Class template `assoc_container_factory`

## Factories and factory specifiers

Given a type `Key` and an `MoveConstructible` type `Entry` implicitly convertible to `const Key&`, a factory of `Entry` elements (implicitly associated to `Key`) is a `DefaultConstructible` entity able to store and retrieve immutable elements of type `Entry`. A factory is governed by an associated equivalence relation defined on `Key` so that no two `Entry` objects convertible to equivalent `Key`s can be stored simultaneously in the factory. Different factory types can use different equivalence relations.

In the following table, `Factory` is a factory of elements of type `Entry`, `f` denotes an object of type `Factory`, `x` denotes a non-const rvalue of type `Entry` and `h` is a value of `Factory::handle_type`.

Factory requirements.
expression | return type | assertion/note pre/post-condition
--- | --- | ---
`Factory::handle_type` | handle to elements of type `T` stored in the factory | `handle_type` is `CopyConstructible` and `CopyAssignable` and its copy and assignment operations never throw an exception.
`f.insert(x);` | `handle_type` | Inserts a copy of `x` if there is no equivalent entry in `f`; returns a handle to the inserted or equivalent element.
`f.erase(h);` | `void` | Erases the element associated to `h`. This operation does not throw.
`f.entry(h);` | `const Entry&` | Returns a reference to the element associated to `h`. This operation does not throw.

Additionally to the basic thread safety guarantee which is implicitly assumed for most classes including the majority of components of the C++ standard library, it is required that the member function `entry` can be invoked simultaneously from different threads, even in the presence of concurrent accesses to `insert` and `erase` (as long as the entry returned by `entry` is not the one which is being erased).

A type `S` is said to be a factory specifier if:

1. One of the following conditions is satisfied:
   1. `is_factory<S>::type` is `boost::mpl::true_`,
   2. `S` is of the form `factory<S'>`.
2. `S`, or `S'` if (b) applies, is an `MPL Lambda Expression` such that invoking it with types (`Entry`, `Key`) resolves to a factory type of `Entry` elements (implicitly associated to `Key`).

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

>     namespace boost{

>     namespace flyweights{

>     struct factory_marker;

>     template<typename T>
>     struct is_factory;

>     template<typename T>
>     struct factory;

>     } // namespace boost::flyweights

>     } // namespace boost

### Class template `is_factory`

Unless specialized by the user, `is_factory<T>::type` is `boost::mpl::true_` if `T` is derived from `factory_marker`, and it is `boost::mpl::false_` otherwise.

### Class template `factory`

`factory<T>` is a syntactic construct meant to indicate that `T` is a factory specifier without resorting to the mechanisms provided by the `is_factory` class template.

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

>     namespace boost{

>     namespace flyweights{

>     template<
>       typename Entry,typename Key,
>       typename Hash=implementation defined,
>       typename Pred=implementation defined,
>       typename Allocator=implementation defined
>     >
>     class hashed_factory_class;

>     template<
>       typename Hash=implementation defined,
>       typename Pred=implementation defined,
>       typename Allocator=implementation defined
>     >
>     struct hashed_factory;

>     } // namespace boost::flyweights

>     } // namespace boost

`hashed_factory_fwd.hpp` forward declares the class templates `hashed_factory_class` and `hashed_factory`.

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

### Class template `hashed_factory_class`

`hashed_factory_class` is a `Factory` implemented with a hashed container.

>     template<
>       typename Entry,typename Key,
>       typename Hash,typename Pred,typename Allocator
>     >
>     class hashed_factory_class
>     {
>     public:
>       typedef implementation defined handle_type;

>       handle_type  insert(Entry&& x);
>       void         erase(handle_type h);
>       const Entry& entry(handle_type h);
>     };

`Hash` is a `DefaultConstructible` `Hash` function object for arguments of type `Key`. `Pred` is a `DefaultConstructible` `BinaryPredicate` inducing an equivalence relation on elements of `Key`. It is required that a `Hash` object return the same value for objects equivalent under `Pred`. The equivalence relation on `Key` associated to the factory is that induced by `Pred`. The default arguments for `Hash` and `Pred` are `boost::hash<Key>` and `std::equal_to<Key>`, respectively. `Allocator` must be an `Allocator` of `Entry` objects. The default argument is `std::allocator<Entry>`. The internal hashed container upon which `hashed_factory_class` is based is constructed with default initialized objects of type `Hash`, `Pred` and `Allocator`.

### Class template `hashed_factory`

`Factory Specifier` for `hashed_factory_class`.

>     template<typename Hash,typename Pred,typename Allocator>
>     struct hashed_factory;

`hashed_factory<Hash,Pred,Allocator>` is an `MPL Metafunction Class` such that the type

>     boost::mpl::apply<
>       hashed_factory<Hash,Pred,Allocator>,
>       Entry,Key
>     >::type

is the same as

>     boost::mpl::apply<
>       hashed_factory_class<boost::mpl::_1,boost::mpl::_2,Hash,Pred,Allocator>,
>       Entry,Key
>     >::type

This implies that `Hash`, `Pred` and `Allocator` can be `MPL Placeholder Expressions` resolving to the actual types used by `hashed_factory_class`.

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

>     namespace boost{

>     namespace flyweights{

>     template<
>       typename Entry,typename Key,
>       typename Hash=implementation defined,
>       typename Pred=implementation defined,
>       typename Allocator=implementation defined
>     >
>     class concurrent_factory_class;

>     template<
>       typename Hash=implementation defined,
>       typename Pred=implementation defined,
>       typename Allocator=implementation defined
>     >
>     struct concurrent_factory;

>     } // namespace boost::flyweights

>     } // namespace boost

`concurrent_factory_fwd.hpp` forward declares the class templates `concurrent_factory_class` and `concurrent_factory`.

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

### Class template `concurrent_factory_class`

`concurrent_factory_class` is a `Factory` implemented with a concurrent hash container. This factory does not require external locking, even in a multithreaded scenarios. It does not require any tracking mechanism either: values no longer referenced by any flyweight are not erased deterministically, but rather they are removed periodically by an internal garbage collector running in a dedicated thread.

>     template<
>       typename Entry,typename Key,
>       typename Hash,typename Pred,typename Allocator
>     >
>     class concurrent_factory_class
>     {
>     public:
>       typedef implementation defined handle_type;

>       handle_type  insert(Entry&& x);
>       void         erase(handle_type h);
>       const Entry& entry(handle_type h);
>     };

`Hash` is a `Hash` function object for arguments of type `Key`. `Pred` is a `DefaultConstructible` `BinaryPredicate` inducing an equivalence relation on elements of `Key`. It is required that a `Hash` object return the same value for objects equivalent under `Pred`. The equivalence relation on `Key` associated to the factory is that induced by `Pred`. The default arguments for `Hash` and `Pred` are `boost::hash<Key>` and `std::equal_to<Key>`, respectively. `Allocator` must be an `Allocator` of `Entry` objects. The default argument is `std::allocator<Entry>`. The internal concurrent container upon which `concurrent_factory_class` is based is constructed with default initialized objects of type `Hash`, `Pred` and `Allocator`.

### Class template `concurrent_factory`

`Factory Specifier` for `concurrent_factory_class`.

>     template<typename Hash,typename Pred,typename Allocator>
>     struct concurrent_factory;

`concurrent_factory<Hash,Pred,Allocator>` is an `MPL Metafunction Class` such that the type

>     boost::mpl::apply<
>       concurrent_factory<Hash,Pred,Allocator>,
>       Entry,Key
>     >::type

is the same as

>     boost::mpl::apply<
>       concurrent_factory_class<boost::mpl::_1,boost::mpl::_2,Hash,Pred,Allocator>,
>       Entry,Key
>     >::type

This implies that `Hash`, `Pred` and `Allocator` can be `MPL Placeholder Expressions` resolving to the actual types used by `concurrent_factory_class`.

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

>     namespace boost{

>     namespace flyweights{

>     template<
>       typename Entry,typename Key,
>       typename Compare=implementation defined,
>       typename Allocator=implementation defined
>     >
>     class set_factory_class;

>     template<
>       typename Compare=implementation defined,
>       typename Allocator=implementation defined
>     >
>     struct set_factory;

>     } // namespace boost::flyweights

>     } // namespace boost

`set_factory_fwd.hpp` forward declares the class templates `set_factory_class` and `set_factory`.

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

### Class template `set_factory_class`

`set_factory_class` is a `Factory` implemented on top of an orderded associative container.

>     template<
>       typename Entry,typename Key,
>       typename Compare,typename Allocator
>     >
>     class set_factory_class
>     {
>     public:
>       typedef implementation defined handle_type;

>       handle_type  insert(Entry&& x);
>       void         erase(handle_type h);
>       const Entry& entry(handle_type h);
>     };

`Compare` is a `DefaultConstructible` `BinaryPredicate` inducing a strict weak ordering on values of `Key`. Two `Key`s `x` and `y` are considered equivalent if `!c(x,y)&&!c(y,x)` for `c` of type `Compare`. The default argument of `Compare` is `std::less<Key>`. `Allocator` must be an `Allocator` of `Entry` objects. The default argument is `std::allocator<Entry>`. The internal container upon which `set_factory_class` is based is constructed with default initialized objects of type `Compare` and `Allocator`.

### Class template `set_factory`

`Factory Specifier` for `set_factory_class`.

>     template<typename Compare,typename Allocator>
>     struct set_factory;

`set_factory<Compare,Allocator>` is an `MPL Metafunction Class` such that the type

>     boost::mpl::apply<
>       set_factory<Compare,Allocator>,
>       Entry,Key
>     >::type

is the same as

>     boost::mpl::apply<
>       set_factory_class<boost::mpl::_1,boost::mpl::_2,Compare,Allocator>,
>       Entry,Key
>     >::type

This implies that `Compare` and `Allocator` can be `MPL Placeholder Expressions` resolving to the actual types used by `set_factory_class`.

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

>     namespace boost{

>     namespace flyweights{

>     template<typename Container>
>     class assoc_container_factory_class;

>     template<typename ContainerSpecifier>
>     struct assoc_container_factory;

>     } // namespace boost::flyweights

>     } // namespace boost

`assoc_container_factory_fwd.hpp` forward declares the class templates `assoc_container_factory_class` and `assoc_container_factory`.

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

### Class template `assoc_container_factory_class`

`assoc_container_factory_class` wraps a suitable associative container to provide a `Factory` interface.

>     template<typename Container>
>     class assoc_container_factory_class
>     {
>     public:
>       typedef typename Container::iterator handle_type;

>       handle_type insert(typename Container::value_type&& x);
>       void        erase(handle_type h);
>       const typename Container::value_type& entry(handle_type h);
>     };

`Container` must be an (ordered or unordered) associative container such that

1. `Container::key_type` is the same as `Container::value_type` (which is the entry type associated to the factory).
2. Unique keys (rather than equivalent keys) are supported.
3. `Container` is stable, i.e. its iterators are not invalidated upon insert or erase operations.

The equivalence relation associated to `assoc_container_factory_class` is the one induced by `Container`. If equivalence of elements of `Container::value_type` is determined solely on the basis of a type `value_type'` to which `value_type` is implicitly convertible, then `assoc_container_factory_class` is a factory of entries of type `value_type` implicitly associated to `value_type'`. For example, the instantiation

>     assoc_container_factory_class<
>       std::set<derived,std::less<base> > // derived inherits from base
>     >

is a factory of `derived` elements implicitly associated to `base`.

### Class template `assoc_container_factory`

`Factory Specifier` for `assoc_container_factory_class`.

>     template<typename ContainerSpecifier>
>     struct assoc_container_factory;

`ContainerSpecifier` must be an `MPL Lambda Expression` resolving, when invoked with (`Entry`, `Key`), to a type `Container` such that `assoc_container_factory_class<Container>` is a factory of `Entry` elements implicitly associated to `Key`.

Tags
Boost.Flyweight reference
Holders

Revised September 27th 2024

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