...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"boost/flyweight/flyweight_fwd.hpp"
synopsis"boost/flyweight/flyweight.hpp"
synopsis
"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: // 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.
"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:
value_type
object).
sizeof(value_type)
.
flyweight
for value_type
results in a reduction in memory usage.
flyweight
is parameterized according to some aspects:
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
.
flyweight
class template.
flyweight
instantiation in the following manner:
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.
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.
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: 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); };
T
can be either:
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 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:
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:
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 offlyweight
is guaranteed to be constructed.
Note: Concurrent execution of this function is not thread safe.
initializer::initializer();
Effects: Executes init()
.
flyweight();
Effects: Constructs aflyweight
object with the valuevalue_type(key_type())
ifflyweight
is key-value orvalue_type()
otherwise.
template<typename... Args>
explicit flyweight(Args&&... args);
Effects: Constructs aflyweight
object with the valuevalue_type(key_type(std::forward<Args>(args)...))
ifflyweight
is key-value orvalue_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 aflyweight
object with the valuevalue_type(key_type(list))
ifflyweight
is key-value orvalue_type(list)
otherwise.
Note: The specialization for a particularstd::initializer_list<V'>
of this member function template is not available unlesskey_type
is constructible fromstd::initializer_list<V'>
.
flyweight(const flyweight& x);
flyweight(flyweight& x);
flyweight(const flyweight&& x);
flyweight(flyweight&& x);
Effects: Constructs aflyweight
object associated to the same value asx
.
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: Ifflyweight
is key-value,value_type
isAssignable
and theKey Extractor
KeyFromValue
must have been supplied as part of thekey_value<>
construct.
Effects: Constructs aflyweight
associated to a copy ofx
or with avalue_type
constructed from a key equivalent to that associated tox
. For non-key-value flyweights,x
is its own key; for key-value flyweights, the key is extracted through use of an object of typeKeyFromValue
.
template<typename V>
flyweight& operator=(std::initializer_list<V> list);
Effects:*this=flyweight(list)
.
Returns:*this
.
Note: The specialization for a particularstd::initializer_list<V'>
of this member function template is not available unlesskey_type
is constructible fromstd::initializer_list<V'>
.
flyweight& operator=(const flyweight& x);
Effects: Associates theflyweight
object with the same value asx
.
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 thevalue_type
associated to theflyweight
object.
Exception safety: Ifflyweight
is not key-value or ifKeyFromValue
was not provided,nothrow
.
const value_type& get()const;
const value_type& operator*()const;
operator const value_type&()const;
Returns: The value associated to theflyweight
object.
Exception safety:nothrow
.
const value_type* operator->()const
Returns: The address of the value associated to theflyweight
object.
Exception safety:nothrow
.
void swap(flyweight& x);
Effects: Swaps the associations tovalue_type
s each flyweight object has. No swapping ofkey_type
orvalue_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: Ifx
andy
are of the same type, returnstrue
if and only if they are associated to the same value; ifx
andy
have different types, returnsx.get()==y.get()
.
Exception safety: Ifx
andy
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<=
).
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: Ifflyweight
is key-value,value_type
isAssignable
and theKey Extractor
KeyFromValue
must have been supplied as part of thekey_value<>
construct.
Effects: Reads an object of typevalue_type
fromin
and assigns it tox
.
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 forx
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
.
Requires:Operation: loading of akey_type
is serializable (XML-serializable).
Effects: The valuek=x.get_key()
is saved intoar
as part of this operation or of a previous saving operation of aflyweight
object with the same key.
Exception safety: Strong with respect tox
. 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 tok'
, a restored copy of the valuek
defined above.
Exception safety: Strong with respect tox'
. 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)