6.1.1. 概要

スカラー割り当てポリシーは、単一のオブジェクトに対する記憶領域の割り当てと開放を行うポリシークラスである。2相テンプレートと状態を持ち得るポリシークラスで構成される。通常はスカラー構築ポリシーと共に使用する。

スカラー割り当てポリシーが提供する機能は次の通り。

割り当てられた記憶領域は、通常は割り当てを行ったポリシーオブジェクトに対して返却されなければならない。割り当て時とは異なるポリシーオブジェクトへと記憶領域を返却したいときは、返却前に記憶領域の所有権の移動を行う必要がある。記憶領域の所有権移動は、例えばあるコンテナオブジェクトから別のコンテナオブジェクトへと要素を格納した記憶領域を直接移動する際に使用する。

初期化オブジェクトは、割り当てポリシーの内部状態の初期化に使用する。あるポリシーオブジェクトaから取得した初期化オブジェクトを用いて別のポリシーオブジェクトbを構築したとき、baと同値とみなせる内部状態を持つ。

スカラー割り当てポリシーとスカラー構築ポリシーを用いたコンテナの例を示す。

例 6.1. スカラー割り当てポリシーとスカラー構築ポリシーを用いたコンテナ

template <typename T>
struct node
{
  T value;
  node* next;
};

template <typename T, class AP, class CP>
class mystack
  :
  public AP::template bind<sizeof(node<T>)>::type,
  public CP::template bind<node<T> >::type
{
private:
  typedef typename AP::template bind<sizeof(node<T>)>::type allocation_policy;
  typedef typename CP::template bind<node<T> >::type construction_policy;
  //
  node<T>* head_;
public:
  mystack()
    : allocation_policy(), construction_policy(), head_(0) {}
  ~mystack() throw()
    { while (!empty()) pop(); }
  bool empty() const
    { return !head_; }
  void push(const T&);
  void pop() throw();
  const T& top() const
    { return head_->value; }
private:
  mystack(const mystack&);
  mystack& operator=(const mystack&);
};

template <typename T, class AP, class CP>
void mystack<T, AP, CP>::push(const T& v)
{
  node<T>* const p = static_cast<node<T>*>(allocation_policy::allocate());
  try {
    const node<T> t = { v, head_ };
    construction_policy::construct(p, t);
  }
  catch (...) {
    allocation_policy::deallocate(p);
    throw;
  }
  head_ = p;
}

template <typename T, class AP, class CP>
void mystack<T, AP, CP>::pop() throw()
{
  node<T>* const p = head_;
  head_ = p->next;
  construction_policy::destruct(p);
  allocation_policy::deallocate(p);
}

mystackクラステンプレートは、スカラー割り当てポリシーとスカラー構築ポリシーを用いたホストクラスで、単純な構成の連結リストによるスタックである。mystack内では、スカラー割り当てポリシーのバックエンドはallocation_policy、スカラー構築ポリシーのバックエンドはconstruction_policyという別名で参照される。

mystackのメンバ関数pushは、次の順序で新規ノードを構築する。

  1. 割り当てポリシーのallocateを呼び、記憶領域を割り当てる

  2. 構築ポリシーのconstructを呼び、要素を構築する

mystackのメンバ関数popは、pushとは逆の順序でノードを破壊する。