fork download
  1. #include <iostream>
  2.  
  3. // define
  4. #define ArggregateCategory(uniqename) Category<__LINE__>
  5.  
  6. namespace arggregate
  7. {
  8.  
  9. namespace detail
  10. {
  11.  
  12. typedef class EOT
  13. {
  14. } EndOfTemplate, EndOfType;
  15.  
  16. /**
  17.  * @brief Aggregate Base
  18. */
  19. class AggregateBase
  20. {
  21. protected:
  22. AggregateBase(void) : m_empty(true) {}
  23. void activate(void) { m_empty = false; }
  24. public:
  25. bool empty(void) const { return m_empty; }
  26. private:
  27. bool m_empty;
  28. };
  29.  
  30. template<typename T>
  31. class ValueType
  32. {
  33. typedef T value_type;
  34. typedef ValueType<value_type> _Myt;
  35. public:
  36. ValueType(void) {}
  37. ValueType(const value_type& rhs) : m_value(rhs) {}
  38. ValueType(const _Myt& rhs) : m_value(rhs.m_value) {}
  39.  
  40. operator value_type& (void) { return m_value; }
  41. operator value_type (void) const { return m_value; }
  42.  
  43. _Myt& operator = (const value_type& rhs) { m_value = rhs; return *this; }
  44. _Myt& operator = (const _Myt& rhs) { m_value = rhs.m_value; return *this; }
  45.  
  46. private:
  47. T m_value;
  48. };
  49.  
  50. /**
  51.  * @brief デフォルト引数判別用の型
  52. */
  53. template<typename T>
  54. class DefaultArgument : public ValueType<T>
  55. {
  56. public:
  57. DefaultArgument(void) {}
  58. DefaultArgument(const T& rhs) : ValueType<T>(rhs) {}
  59. };
  60.  
  61. }
  62.  
  63. /**
  64.  * @brief カテゴリー
  65. */
  66. template<int LINE>
  67. class Category
  68. {
  69. template<typename Aggregate>
  70. class Instance
  71. {
  72. static Aggregate m_aggregate;
  73. public:
  74. static Aggregate& GetInstance(void) { return m_aggregate; }
  75. };
  76.  
  77. template<typename T, typename Aggregate>
  78. class AggregateList
  79. {
  80. public:
  81. static void add(const T& rhs)
  82. {
  83. Instance<typename Aggregate::InstantiateType>::GetInstance().add(rhs);
  84. AggregateList<T, typename Aggregate::NextType>::add(rhs);
  85. }
  86. };
  87. template<typename T>
  88. class AggregateList<T, detail::EOT>
  89. {
  90. public:
  91. static void add(const T&) {}
  92. };
  93.  
  94. public:
  95. /**
  96. * @brief 型定義
  97. */
  98. template<typename T, typename Aggregate>
  99. class Decl : public detail::ValueType<T>
  100. {
  101. typedef Decl<T, Aggregate> _Myt;
  102. public:
  103. typedef _Myt Type;
  104. public:
  105. Decl(const T& rhs) : detail::ValueType<T>(rhs), m_default(false)
  106. {
  107. AggregateList<T, Aggregate>::add(rhs);
  108. }
  109. Decl(const detail::DefaultArgument<T>& rhs) : detail::ValueType<T>(rhs), m_default(true)
  110. {
  111. // デフォルト引数の場合は集計しない
  112. }
  113.  
  114. public:
  115. bool is_default(void) const { return m_default; }
  116. private:
  117. bool m_default;
  118. };
  119.  
  120. /**
  121. * @brief デフォルト値の取得クラス
  122. */
  123. template<typename T, typename SimpleAggregate>
  124. static detail::DefaultArgument<T> Value(const T& defalut_value)
  125. {
  126. return Instance<SimpleAggregate>::GetInstance().empty() ?
  127. defalut_value : static_cast<T>(Instance<SimpleAggregate>::GetInstance().value());
  128. }
  129. };
  130.  
  131. template<int LINE>
  132. template<typename Aggregate>
  133. Aggregate Category<LINE>::Instance<Aggregate>::m_aggregate;
  134.  
  135. /**
  136.  * @brief 最小値
  137. */
  138. template<typename T, typename Next=detail::EOT>
  139. class Min : public detail::AggregateBase
  140. {
  141. T m_value;
  142. public:
  143. typedef Next NextType;
  144. typedef Min<T, detail::EOT> InstantiateType;
  145.  
  146. public:
  147. void add(const T& value)
  148. {
  149. if( empty() || value < m_value )
  150. {
  151. m_value = value;
  152. activate();
  153. }
  154. }
  155. T value(void) const { return m_value; }
  156. };
  157.  
  158. /**
  159.  * @brief 最大値
  160. */
  161. template<typename T, typename Next=detail::EOT>
  162. class Max : public detail::AggregateBase
  163. {
  164. T m_value;
  165. public:
  166. typedef Next NextType;
  167. typedef Max<T, detail::EOT> InstantiateType;
  168.  
  169. public:
  170. void add(const T& value)
  171. {
  172. if( empty() || value > m_value )
  173. {
  174. m_value = value;
  175. activate();
  176. }
  177. }
  178. T value(void) const { return m_value; }
  179. };
  180.  
  181. }
  182.  
  183. // 集計カテゴリの定義(現状は行ごとにカテゴリ化される。)
  184. typedef ::arggregate::ArggregateCategory(test) Arggregate1;
  185. typedef ::arggregate::ArggregateCategory(test) Arggregate2;
  186.  
  187. typedef ::arggregate::Min<int, ::arggregate::Max<int> > MinMax;
  188.  
  189. void f1(Arggregate1::Decl< int, ::arggregate::Min<int> >::Type x=Arggregate1::Value< int, ::arggregate::Min<int> >(1000) )
  190. {
  191. if( x.is_default() ) ::std::cout << x << ::std::endl;
  192. }
  193.  
  194. void f2(Arggregate2::Decl< int, MinMax >::Type x1=Arggregate2::Value< int, ::arggregate::Min<int> >(-1)
  195. , Arggregate2::Decl< int, MinMax >::Type x2=Arggregate2::Value< int, ::arggregate::Max<int> >(1000) )
  196. {
  197. ::std::cout << x1 << ":" << x2 << ::std::endl;
  198. }
  199.  
  200. int main(void)
  201. {
  202. {
  203. ::std::cout << "----- f1 ----- " << ::std::endl;
  204.  
  205. f1(); // 集計情報 0 のため 通常デフォルト引数が渡される
  206. for( int i=10; i > 0; --i )
  207. {
  208. f1(i); // 通常使用
  209. }
  210. f1(); // 集計した結果の最小値がデフォルト引数となる
  211. }
  212.  
  213. {
  214. ::std::cout << "----- f2 ----- " << ::std::endl;
  215.  
  216. f2(); // 集計情報 0 のため 通常デフォルト引数が渡される
  217. for( int i=10; i > 0; --i )
  218. {
  219. f2(i); // 第一引数のみ指定、第二引数にも集計結果が反映される
  220. }
  221. f2(); // 集計した結果の最小値がデフォルト引数となる
  222. }
  223.  
  224. return 0;
  225. }
  226.  
  227.  
  228.  
Success #stdin #stdout 0.02s 2724KB
stdin
Standard input is empty
stdout
----- f1 ----- 
1000
1
----- f2 ----- 
-1:1000
10:1000
9:10
8:10
7:10
6:10
5:10
4:10
3:10
2:10
1:10
1:10