Boost C++ 库

……世界上最受推崇和设计精良的 C++ 库项目之一。 Herb SutterAndrei AlexandrescuC++ 编码规范

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 的实例化为键值轻量级对象。value_type 是轻量级对象访问的值的类型,而值查找基于关联的 key_type 值。key_value 必须是 可移动构造的,并且 value_type 必须可以从 key_type 构造;此外,key_value 必须符合所使用的工厂类型强加的任何额外要求。对于键值轻量级对象,保证创建或赋值轻量级对象最多导致一次 value_type 对象的构造(或在某些特定情况下复制构造),并且这种构造仅在轻量级工厂中以前不存在等效值的情况下发生。

如果提供,类型 Arg1、……、Arg5 必须是以下任何一种,顺序无关紧要:

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

静态数据初始化

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

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

构造函数、复制和赋值

flyweight();
效果:如果 flyweight 是键值,则构造值为 value_type(key_type())flyweight 对象;否则构造值为 value_type() 的对象。
template<typename... Args>
explicit flyweight(Args&&... args);
效果:如果 flyweight 是键值,则构造值为 value_type(key_type(std::forward<Args>(args)...))flyweight 对象;否则构造值为 value_type(std::forward<Args>(args)...) 的对象。
注意:在没有可变参数模板支持的编译器中,实现会用多个重载来代替此构造函数,这些重载最多接受用户可全局 配置 的最大数量的 const/非 const 左值/右值引用参数组合。
template<typename V>
flyweight(std::initializer_list<V> list);
效果:如果 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 是键值,则必须已将 键提取器 KeyFromValue 作为 key_value<> 结构的一部分提供。
效果:构造与 x 的副本关联的 flyweight,或者构造从与 x 关联的键等效的键构造的 value_type。对于非键值轻量级对象,x 是其自身的键;对于键值轻量级对象,键是通过使用 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 不是键值,则为 noexcept;否则,如果未提供 KeyFromValue,或 noexcept(std::declval<KeyFromValue>()(std::declval<const value_type&>()))
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;
效果:交换每个轻量级对象与 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是键值对,value_type必须是可复制构造的,并且必须在key_value<>构造中提供键提取器 KeyFromValue
效果:in读取value_type类型的对象并将其赋值给x
返回值:in

哈希支持

支持使用std::hashboost::hashflyweight进行哈希。在这两种情况下,计算都不涉及对关联的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;
返回值:x的哈希值,供Boost.ContainerHash使用。

配置宏

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可序列化的)。
效果:在此操作或先前保存具有相同键的flyweight对象的操作中,将值k=x.get_key()保存到ar中。
异常安全:相对于x而言是强大的。如果抛出异常,ar可能处于不一致状态。
操作:从输入存档(XML存档)ar加载flyweight x'
需求:key_type是可序列化的(XML可序列化的)。
效果:x'关联到从与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