OSDN Git Service

7cfeccda4864e51afda7b5714484dd900ae8c46a
[simplecms/utakata.git] / src / common / factory.h
1 // テンプレートパラメータとして渡された型を生成するための
2 // 各種テンプレートを提供します。
3 //
4 // Factoryは、単純に渡された型を生成して返すためだけのクラス
5 // です。InheritFactoryは、ある型の派生クラスを生成するための
6 // クラスです。
7 // PermutationFactoryは、InheritFactoryを利用して、Factory置換を
8 // 行うためのクラスです。
9 //
10 // Factory<Hoge> o();
11 // Hoge* p = o.Create();
12 // InheritFactory<Hoge, Hoge2> o2();
13 // Hoge2* p2 = o2.Create();
14 // p = o2->Create();
15 //
16 // PermutationFactory<Hoge, Hoge2> pf;
17 // p = pf.Create();
18 // pf.ReplaceFactory(Hoge3());  // Hoge3 is inherit from Hoge
19 // p = pf.Create();  // Create `Hoge3` Instance!
20 #ifndef _HOME_DERUI_DEVELOP_UTAKATA_SRC_COMMON_FACTORY_H_
21 #define _HOME_DERUI_DEVELOP_UTAKATA_SRC_COMMON_FACTORY_H_
22
23 #include "src/common/uncopyable.h"
24 #include "src/common/scoped_ptr.h"
25
26 namespace utility {
27
28 template<class T>
29 class Factory : private utility::Uncopyable {
30   // テンプレートパラメータで渡された型を新規に生成して
31   // 返すFactoryテンプレートです。
32   // 生成は全てnewで行われるため、このクラスから生成したインスタンス
33   // については、利用する側に解体責任が発生します。
34  public:
35   virtual ~Factory() {}
36
37   // テンプレートで渡された型を新規に生成します。
38   virtual T* Create() const {reutrn new T;}
39 };
40
41 template<class T, class S>
42 class InheritFactory : public Factory<T> : private utility::Uncopyable {
43   // テンプレートパラメータ`S`で渡された型を新規に生成して
44   // 返すFactoryテンプレートです。
45   // 生成は全てnewで行われるため、このクラスから生成したインスタンス
46   // については、利用する側に解体責任が発生します。
47   // テンプレートパラメータ`S`は、テンプレートパラメータ`T`の
48   // 派生クラスである必要があります。
49  public:
50   virtual T* Create() {
51     return new S;
52   }
53 };
54
55 /**
56  * @brief クラス置換を擬似的に実現するためのテンプレート
57  * このクラスでは、SはTの派生クラスとして、Sを切り替えてnewすることが
58  * 可能であるような動作をする。
59  */
60 template<class T, class S>
61 class PermutationFactory {
62  public:
63
64   PermutationFactory() : factory_(new InheritFactory(T, S)) {}
65   /**
66    * @brief 基底の型へのポインタを返す。
67    */
68   T* Create() {return factory_->Creater();}
69
70   /**
71    * @brief 基本型のfactoryを返すが、これは実際には派生型を返すものである。
72    */
73   smart_ptr<Factory<T> > factory() const {
74     return factory_;
75   }
76
77   /**
78    * @brief factoryの置換を行う。
79    * 置換を行うことが出来るのは、UがTの派生型であるときだけである。
80    */
81   template<class U>
82   void ReplaceFactory(U p) {factory_.reset(new InheritFactory(T, U));}
83
84  private:
85
86   scoped_ptr<Factory<T> > factory_;
87 };
88 }; // end of namespace utility
89
90 #endif /* _C:_MEADOW_DEVELOP_UTAKATA_SRC_COMMON_FACTORY_H_ */