Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Boost.Flyweight flyweight reference



Contents

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

// 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_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 boost

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

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:

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:

These aspects impact the internal structure and behavior of the flyweight instantiation in the following manner: 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.

#include <initializer_list>

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

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

Instantiation types

T can be either:

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:

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:

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

Convertibility to the underlying types

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.

Modifiers

void swap(flyweight& x);
Effects: Swaps the associations to value_types 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_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.

Hash support

Support is provided for hashing flyweights 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.

Configuration macros

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.

Header "boost/flyweight/serialize.hpp" synopsis

serialize.hpp includes the necessary functionality for interoperability of flyweight with Boost.Serialization.

Serialization

flyweights 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 flyweights result in their common key_type value being stored only once, regardless of whether key_type is tracked by Boost.Serialization or not.

Operation: saving of a flyweight object x to an output archive (XML archive) ar.
Requires: 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.
Operation: loading of a 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)