Boost C++ 库

...世界上最受推崇和专业设计的 C++ 库项目之一。 Herb SutterAndrei Alexandrescu, C++ 编码标准

Boost.Flyweight flyweight 参考



目录

头文件 "boost/flyweight/flyweight_fwd.hpp" 概要

#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) noexcept(see below);

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

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

} // namespace boost::flyweights
} // namespace boost

flyweight_fwd.hpp 前向声明了类模板 flyweight 及其相关的全局函数和类模板特化。

头文件 "boost/flyweight/flyweight.hpp" 概要

类模板 flyweight

flyweight<...> 类型的对象提供对 flyweight<...>::value_type 类型的不可变值的访问,与使用普通的 value_type 对象相比,具有以下优势

因此,如果冗余级别(对象总数与不同值的比率)足够高,则用 flyweight 的适当实例化替换 value_type 会减少内存使用量。

flyweight 根据某些方面进行参数化

这些方面以下列方式影响 flyweight 实例化的内部结构和行为在接下来的内容中,我们隐含地假设 key_type 等价性是指由使用的工厂类引起的等价关系。此外,如果两个 value_type 的值是从等价键构造的,或者是从等价键构造的对象副本,则认为它们是等价的。

#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) noexcept;
  flyweight(flyweight& x) noexcept;
  flyweight(const flyweight&& x) noexcept;
  flyweight(flyweight&& x) noexcept;
 
  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) noexcept;  

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

  // convertibility to underlying type:

  const key_type&   get_key() const noexcept(see below);
  const value_type& get() const noexcept;
  const value_type& operator*() const noexcept;
  operator const    value_type&() const noexcept;  
  const value_type* operator->() const noexcept;

  // modifiers:

  void swap(flyweight& x) noexcept;
};

实例化类型

T 可以是

在第一种情况下,嵌套类型 key_typevalue_type 都等于 T。在第二种情况下,key_type=Keyvalue_type=Value;我们称 flyweight 的实例化为键值 flyweight。value_type 是 flyweight 对象提供访问的值的类型,而值查找基于关联的 key_type 值。key_value 必须是 MoveConstructible,并且 value_type 必须可以从 key_type 构造;此外,key_value 必须符合所使用的工厂类型施加的任何额外要求。对于键值 flyweight,保证 flyweight 对象的创建或赋值最多导致一次 value_type 对象的构造(或在某些特定情况下进行复制构造),并且此构造仅在 flyweight 工厂中先前不存在等效值的情况下发生。

如果提供类型 Arg1, ... , Arg5,则必须是以下任何一种,顺序不限

任何方面都不能指定两次。flyweight 实例化的每个内部组件都是通过使用相应的说明符获得的;例如,工厂来自给定工厂说明符的特定 (MPL) 调用,内部互斥锁来自给定的锁定策略,等等。默认配置参数为

静态数据初始化

给定 flyweight 实例化(工厂实例等)的静态数据在程序的动态初始化阶段构造,并且总是在实例化类的首次程序范围使用之前。当需要更多地控制构造时刻时,可以使用以下实用程序。

static bool init();
效果: 在执行此函数后,保证与 flyweight 实例化关联的静态数据将被构造。
注意: 并发执行此函数不是线程安全的。
initializer::initializer();
效果: 执行 init()

构造函数、复制和赋值

flyweight();
效果: 如果 flyweight 是键值 flyweight,则构造一个值为 value_type(key_type())flyweight 对象;否则构造一个值为 value_type() 的对象。
template<typename... Args>
explicit flyweight(Args&&... args);
效果: 如果 flyweight 是键值 flyweight,则构造一个值为 value_type(key_type(std::forward<Args>(args)...))flyweight 对象;否则构造一个值为 value_type(std::forward<Args>(args)...) 的对象。
注意: 在没有可变参数模板支持的编译器中,实现将此构造函数替换为多个重载,这些重载接受最多可由用户全局 配置 的最大数量的 const/non-const 左值/右值引用参数的任何组合。
template<typename V>
flyweight(std::initializer_list<V> list);
效果: 如果 flyweight 是键值 flyweight,则构造一个值为 value_type(key_type(list))flyweight 对象;否则构造一个值为 value_type(list) 的对象。
注意: 除非 key_type 可从 std::initializer_list<V'> 构造,否则此成员函数模板的特定 std::initializer_list<V'> 特化不可用。
flyweight(const flyweight& x) noexcept;
flyweight(flyweight& x) noexcept;
flyweight(const flyweight&& x) noexcept;
flyweight(flyweight&& x) noexcept;
效果: 构造一个与 x 关联到相同值的 flyweight 对象。
explicit flyweight(const value_type& x);
explicit flyweight(value_type& x);
explicit flyweight(const value_type&& x);
explicit flyweight(value_type&& x);
要求: value_type 可以从参数类型构造。如果 flyweight 是键值 flyweight,则必须已提供 Key Extractor KeyFromValue 作为 key_value<> 构造的一部分。
效果: 构造一个与 x 的副本关联的 flyweight,或与从等效于与 x 关联的键构造的 value_type 关联的 flyweight。对于非键值 flyweight,x 本身就是其键;对于键值 flyweight,键通过使用 KeyFromValue 类型的对象提取。
template<typename V>
flyweight& operator=(std::initializer_list<V> list);
效果: *this=flyweight(list)
返回: *this
注意: 除非 key_type 可从 std::initializer_list<V'> 构造,否则此成员函数模板的特定 std::initializer_list<V'> 特化不可用。
flyweight& operator=(const flyweight& x) noexcept;
效果:flyweight 对象与 x 关联到相同的值。
返回: *this
flyweight& operator=(const value_type& x);
flyweight& operator=(value_type&& x);
效果: *this=flyweight(x)(第一个重载),*this=flyweight(std::move(x))(第二个重载)。
返回: *this

到底层类型的可转换性

const key_type& get_key() const noexcept(见下文);
返回: 用于构造与 flyweight 对象关联的 value_type 的键的副本。
注意: 如果 flyweight 不是键值 flyweight,或者未提供 KeyFromValue,或者 noexcept(std::declval<KeyFromValue>()(std::declval<const value_type&>())),则为 noexcept
const value_type& get() const noexcept;
const value_type& operator*() const noexcept;
operator const value_type&() const noexcept;
返回:flyweight 对象关联的值。
const value_type* operator->() const noexcept;
返回:flyweight 对象关联的值的地址。

修改器

void swap(flyweight& x) noexcept;
效果: 交换每个 flyweight 对象具有的与 value_type 的关联。不进行 key_typevalue_type 对象的交换。

比较运算符

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) noexcept(见下文);
返回: 如果 xy 是相同类型,则当且仅当它们与相同的值关联时,才返回 true;如果 xy 具有不同的类型,则返回 x.get()==y.get()
注意: 如果 xy 是相同类型,则为 noexcept
template<
  typename T1,typename Arg11,...,typename Arg15,
  typename T2
>
bool operator ==(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y);
返回: x.get()==y
template<
  typename T1,
  typename T2,typename Arg21,...,typename Arg25
>
bool operator ==(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y);
返回: 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);
返回: x.get()<y.get()
template<
  typename T1,typename Arg11,...,typename Arg15,
  typename T2
>
bool operator <(const flyweight<T1,Arg11,...,Arg15>& x,const T2& y);
返回: x.get()<y
template<
  typename T1,
  typename T2,typename Arg21,...,typename Arg25
>
bool operator <(const T1& x,const flyweight<T2,Arg21,...,Arg25>& y);
返回: 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) noexcept(见下文);

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!=, >, >=, <= 中的任何一个。)

返回: 当且仅当以下情况时,返回 true
!(x==y) (OP!=),
  y< x  (OP),
!(x< y) (OP>=),
!(y< x) (OP<=).
注意: 如果 OP!= 并且 xy 是相同类型,则为 noexcept

特化算法

template<typename T,typename Arg1,...,typename Arg5>
inline void swap(
  flyweight<T,Arg1,...,Arg5>& x,flyweight<T,Arg1,...,Arg5>& y) noexcept;
效果: 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);
效果: out<<x.get()
返回: 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);
要求: 如果 flyweight 是键值 flyweight,则 value_typeCopyConstructible,并且必须已提供 Key Extractor KeyFromValue 作为 key_value<> 构造的一部分。
效果:in 读取 value_type 类型的对象,并将其赋值给 x
返回: in

哈希支持

flyweight 提供使用 std::hashboost::hash 进行哈希运算的支持。在这两种情况下,计算都不涉及哈希关联的 value_type 对象本身;因此,value_type 是否可哈希无关紧要。对于相同的 flyweight 对象,std::hashboost::hash 给出的结果通常会不同。
注意: 可以 禁用 哈希支持,以解决与用户已定义此功能的代码的冲突。

namespace std{
template<typename T,typename Arg1,...,typename Arg5>
struct hash<boost::flyweight<T,Arg1,...,Arg5> >;
}
此模板特化满足 [unord.hash] 中类模板 std::hash 的要求。其函数调用运算符为 noexcept
template<typename T,typename Arg1,...,typename Arg5>
inline std::size_t hash_value(const flyweight<T,Arg1,...,Arg5>& x) noexcept;
返回: 用于 Boost.ContainerHashx 的哈希值。

配置宏

BOOST_FLYWEIGHT_LIMIT_PERFECT_FWD_ARGS
在没有可变参数模板支持的编译器中,全局定义此宏以设置 flyweight 转发构造函数 接受的最大参数数量,默认值为 5。
BOOST_FLYWEIGHT_DISABLE_HASH_SUPPORT
如果已定义,则不提供哈希支持。这对于处理用户已定义通用 flyweight 哈希的遗留代码可能很有用。

头文件 "boost/flyweight/serialize.hpp" 概要

serialize.hpp 包含 flyweightBoost.Serialization 互操作的必要功能。

序列化

可以通过 Boost.Serialization 归档和检索 flyweight。支持常规归档和 XML 归档。序列化以高效的方式完成,以便保存等效的 flyweight 会导致其公共 key_type 值仅存储一次,无论 key_type 是否被 Boost.Serialization 追踪

操作:将 flyweight 对象 x 保存到输出归档(XML 归档)ar
要求: key_type 是可序列化的(XML 可序列化的)。
效果:k=x.get_key() 作为此操作的一部分或先前保存具有相同键的 flyweight 对象的操作的一部分保存到 ar 中。
异常安全性: 对于 x 具有强异常安全性。如果抛出异常,ar 可能处于不一致状态。
操作:从输入归档(XML 归档)ar 加载 flyweight x'
要求: key_type 是可序列化的(XML 可序列化的)。
效果: x' 与从等效于 k' 的键构造的值关联,k' 是上面定义的值 k 的恢复副本。
异常安全性: 对于 x' 具有强异常安全性。如果抛出异常,ar 可能处于不一致状态。



修订于 2024 年 9 月 28 日

© 版权所有 2006-2024 Joaquín M López Muñoz。根据 Boost 软件许可,1.0 版分发。(请参阅随附文件 LICENSE_1_0.txt 或在 https://boost.ac.cn/LICENSE_1_0.txt 复制)