iutest  1.17.1.0
iutest_genparams.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_
16 #define INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_
17 
18 #if IUTEST_HAS_PARAM_TEST
19 
20 namespace iutest {
21 namespace detail
22 {
23 
24 //======================================================================
25 // declare
26 #if IUTEST_HAS_CONCAT
27 template<typename Generator1, typename Generator2>class iuConcatParamHolder;
28 #endif
29 
30 //======================================================================
31 // class
35 template<typename T>
36 class iuIParamGenerator
37 {
38 public:
39  typedef T type;
40 public:
41  typedef iuIParamGenerator<T>* (*Generator)();
42 public:
43  virtual ~iuIParamGenerator() {}
44 public:
45  virtual void Begin() = 0;
46  virtual T GetCurrent() const = 0;
47  virtual void Next() = 0;
48  virtual bool IsEnd() const = 0;
49 };
50 
54 template<typename T>
55 class iuParamGenerator : public iuIParamGenerator<T>
56 {
57  typedef iuIParamGenerator<T> _Interface;
58  typedef iuParamGenerator<T> _Myt;
59 public:
60  typedef T type;
61 public:
62  iuParamGenerator(_Interface* pInterface=NULL) : m_pInterface(pInterface) {} // NOLINT
63 
64 public:
65  operator iuIParamGenerator<T>* () const { return m_pInterface; }
66 
67 public:
68 #if IUTEST_HAS_CONCAT
69  template<typename Other>
70  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
71  {
72  return iuConcatParamHolder<_Myt, Other>(*this, g);
73  }
74 #endif
75 
76 public:
77  virtual void Begin() IUTEST_CXX_OVERRIDE { m_pInterface->Begin(); }
78  virtual T GetCurrent() const IUTEST_CXX_OVERRIDE { return m_pInterface->GetCurrent(); }
79  virtual void Next() IUTEST_CXX_OVERRIDE { m_pInterface->Next(); }
80  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE { return m_pInterface->IsEnd(); }
81 private:
82  _Interface* m_pInterface;
83 };
84 
89 template<typename T>
90 class iuRangeParamsGenerator : public iuIParamGenerator<T>
91 {
92  T m_begin;
93  T m_end;
94  T m_step;
95  T m_cur;
96 public:
103  iuRangeParamsGenerator(T begin, T end, T step)
104  : m_begin(begin)
105  , m_end(end)
106  , m_step(step)
107  , m_cur(begin)
108  {
109  }
110 
111 public:
112  virtual void Begin() IUTEST_CXX_OVERRIDE { m_cur = m_begin; }
113  virtual T GetCurrent() const IUTEST_CXX_OVERRIDE { return m_cur; }
114  virtual void Next() IUTEST_CXX_OVERRIDE { m_cur = static_cast<T>(m_cur + m_step); }
115  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE { return !(m_cur < m_end); }
116 };
117 
121 class iuBoolParamsGenerator : public iuIParamGenerator<bool>
122 {
123  int m_n;
124  bool m_cur;
125 public:
126  iuBoolParamsGenerator()
127  : m_n(0)
128  , m_cur(false)
129  {}
130 
131 public:
132  virtual void Begin() IUTEST_CXX_OVERRIDE { m_cur = false; m_n = 0; }
133  virtual bool GetCurrent() const IUTEST_CXX_OVERRIDE { return m_cur; }
134  virtual void Next() IUTEST_CXX_OVERRIDE { ++m_n; m_cur = !m_cur; }
135  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE { return m_n >= 2; }
136 };
137 
142 template<typename T>
143 class iuValuesInParamsGenerator : public iuIParamGenerator<T>
144 {
145  typedef ::std::vector<T> params_t;
146  params_t m_values;
147  typename params_t::const_iterator m_it;
148 public:
149  explicit iuValuesInParamsGenerator(const params_t& values)
150  : m_values(values) {}
151  template<typename Container>
152  explicit iuValuesInParamsGenerator(const Container& values)
153  {
154  m_values.insert(m_values.end(), values.begin(), values.end());
155  }
156 #if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
157  template<typename TT, size_t SIZE>
158  explicit iuValuesInParamsGenerator(const TT (&values)[SIZE])
159  {
160  m_values.insert(m_values.end(), values, values + SIZE);
161  }
162 #endif
163 
164  template<typename Ite>
165  iuValuesInParamsGenerator(Ite begin, Ite end)
166  {
167  m_values.insert(m_values.end(), begin, end);
168  }
169 
170 #if IUTEST_HAS_INITIALIZER_LIST
171  iuValuesInParamsGenerator(::std::initializer_list<T> l)
172  {
173  m_values.insert(m_values.end(), l.begin(), l.end());
174  }
175 #endif
176 
177 public:
178  virtual void Begin() IUTEST_CXX_OVERRIDE { m_it = m_values.begin(); }
179  virtual T GetCurrent() const IUTEST_CXX_OVERRIDE { return *m_it; }
180  virtual void Next() IUTEST_CXX_OVERRIDE { ++m_it; }
181  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE { return (m_it == m_values.end()); }
182 };
183 
184 
185 #if IUTEST_HAS_CONCAT
186 
189 template<typename G1, typename G2>
190 class iuConcatParamHolder
191 {
192  typedef iuConcatParamHolder<G1, G2> _Myt;
193 public:
194  iuConcatParamHolder(const G1& g1, const G2& g2)
195  : m_g1(g1), m_g2(g2) {}
196 
197 private:
198  iuConcatParamHolder() IUTEST_CXX_DELETED_FUNCTION;
199 
200 public:
201  template<typename T>
202  operator iuIParamGenerator<T>* ()
203  {
204  params_t<T> params;
205  params.append(m_g1);
206  params.append(m_g2);
207  return new iuValuesInParamsGenerator<T>(params.val);
208  }
209 
210  template<typename Other>
211  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
212  {
213  return iuConcatParamHolder<_Myt, Other>(*this, g);
214  }
215 
216 private:
217  template<typename T>
218  struct params_t
219  {
220  typedef iuIParamGenerator<T> IParamGenerater;
221  ::std::vector<T> val;
222 
223  void append(IParamGenerater* gen)
224  {
225  detail::scoped_ptr<IParamGenerater> p(gen);
226  for( p->Begin(); !p->IsEnd(); p->Next() )
227  {
228  val.push_back(p->GetCurrent());
229  }
230  }
231  template<typename U>
232  void append(iuParamGenerator<U>& gen)
233  {
234  for( gen.Begin(); !gen.IsEnd(); gen.Next() )
235  {
236  val.push_back(static_cast<T>(gen.GetCurrent()));
237  }
238  }
239  };
240 private:
241  G1 m_g1;
242  G2 m_g2;
243 };
244 #endif
245 
246 
247 #if IUTEST_HAS_VARIADIC_VALUES
248 template<typename... Args>
249 class iuValueArray
250 {
251  typedef tuples::tuple<Args...> _MyTuple;
252  typedef iuValueArray<Args...> _Myt;
253 
254  template<typename T>
255  struct make_array
256  {
257  T val[sizeof...(Args)];
258 
259  template<typename U>
260  void operator ()(int index, const U& value) { val[index] = value; }
261 
262  explicit make_array(const _MyTuple& t)
263  {
264  tuples::tuple_foreach(t, *this);
265  }
266  };
267 public:
268  explicit iuValueArray(const Args&... args)
269  : v(args...)
270  {}
271 
272 #if defined(__clang__) && defined(IUTEST_LIBSTDCXX_VERSION) && IUTEST_LIBSTDCXX_VERSION >= 40900
273 #if IUTEST_HAS_RVALUE_REFS
274  // https://stackoverflow.com/questions/23374953/why-does-this-exceed-the-maximum-recursive-template-depth
275  iuValueArray(const iuValueArray& rhs)
276  : v(rhs.v) {}
277  iuValueArray(iuValueArray&& rhs)
278  : v(rhs.v) {}
279 #endif
280 #endif
281 
282 public:
283  template<typename T>
284  operator iuIParamGenerator<T>* () const
285  {
286  make_array<T> ar(v);
287 #if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
288  return new iuValuesInParamsGenerator<T>(ar.val);
289 #else
290  return new iuValuesInParamsGenerator<T>(ar.val, ar.val + IUTEST_PP_COUNTOF(ar.val));
291 #endif
292  }
293 
294 public:
295 #if IUTEST_HAS_CONCAT
296  template<typename Other>
297  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
298  {
299  return iuConcatParamHolder<_Myt, Other>(*this, g);
300  }
301 #endif
302 
303 private:
304  _MyTuple v;
305 };
306 
307 #else
308 
309 /*
310 template<typename A1, typename A2>
311 class iuValueArray2
312 {
313 typedef iuValueArray2<A1, A2> _Myt;
314 public:
315 iuValueArray2(A1 a1, A2 a2) : v1(a1), v2(a2)
316 {}
317 public:
318 template<typename T>
319 operator iuIParamGenerator<T>* () const
320 {
321 const T val[] = { static_cast<T>(v1), static_cast<T>(v2) };
322 return new iuValuesInParamsGenerator<T>(val);
323 }
324 public:
325 template<typename Other>
326 iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
327 {
328 return iuConcatParamHolder<_Myt, Other>(*this, g);
329 }
330 private:
331 A1 v1; A2 v2;
332 };
333 */
334 
339 #define IIUT_DECL_VALUEARRAY_CONSTRUCT_(i, p1, p2) IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
340 #define IIUT_DECL_VALUEARRAY_STATICCAST_(i, p1, p2) static_cast<p1>(IUTEST_PP_CAT(p2, i))
341 #define IIUT_DECL_VALUEARRAY_VARIABLE_(i, p1, p2) IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
342 #if IUTEST_HAS_CONCAT
343 # define IIUT_DECL_VALUEARRAY_CONCAT_() \
344  template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
345  return iuConcatParamHolder<_Myt, Other>(*this, g); }
346 #else
347 # define IIUT_DECL_VALUEARRAY_CONCAT_()
348 #endif
349 
350 
351 #define IIUT_DECL_VALUEARRAY_(n) \
352  template< IUTEST_PP_ENUM_PARAMS(n, typename A) > \
353  class IUTEST_PP_CAT(iuValueArray, n) { \
354  typedef IUTEST_PP_CAT(iuValueArray, n)< IUTEST_PP_ENUM_PARAMS(n, A) > _Myt; \
355  public: \
356  IUTEST_PP_CAT(iuValueArray, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, A, a) ) \
357  : IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_VALUEARRAY_CONSTRUCT_, v, a) {} \
358  template<typename T>operator iuIParamGenerator<T>* () const { \
359  const T val[] = { IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_VALUEARRAY_STATICCAST_, T, v) }; \
360  return new iuValuesInParamsGenerator<T>(val); \
361  } \
362  IIUT_DECL_VALUEARRAY_CONCAT_() \
363  private: IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_VALUEARRAY_VARIABLE_, A, v) \
364  }
365 
369 IIUT_DECL_VALUEARRAY_(1);
370 IIUT_DECL_VALUEARRAY_(2);
371 IIUT_DECL_VALUEARRAY_(3);
372 IIUT_DECL_VALUEARRAY_(4);
373 IIUT_DECL_VALUEARRAY_(5);
374 IIUT_DECL_VALUEARRAY_(6);
375 IIUT_DECL_VALUEARRAY_(7);
376 IIUT_DECL_VALUEARRAY_(8);
377 IIUT_DECL_VALUEARRAY_(9);
378 IIUT_DECL_VALUEARRAY_(10);
379 IIUT_DECL_VALUEARRAY_(11);
380 IIUT_DECL_VALUEARRAY_(12);
381 IIUT_DECL_VALUEARRAY_(13);
382 IIUT_DECL_VALUEARRAY_(14);
383 IIUT_DECL_VALUEARRAY_(15);
384 IIUT_DECL_VALUEARRAY_(16);
385 IIUT_DECL_VALUEARRAY_(17);
386 IIUT_DECL_VALUEARRAY_(18);
387 IIUT_DECL_VALUEARRAY_(19);
388 IIUT_DECL_VALUEARRAY_(20);
389 IIUT_DECL_VALUEARRAY_(21);
390 IIUT_DECL_VALUEARRAY_(22);
391 IIUT_DECL_VALUEARRAY_(23);
392 IIUT_DECL_VALUEARRAY_(24);
393 IIUT_DECL_VALUEARRAY_(25);
394 IIUT_DECL_VALUEARRAY_(26);
395 IIUT_DECL_VALUEARRAY_(27);
396 IIUT_DECL_VALUEARRAY_(28);
397 IIUT_DECL_VALUEARRAY_(29);
398 IIUT_DECL_VALUEARRAY_(30);
399 IIUT_DECL_VALUEARRAY_(31);
400 IIUT_DECL_VALUEARRAY_(32);
401 IIUT_DECL_VALUEARRAY_(33);
402 IIUT_DECL_VALUEARRAY_(34);
403 IIUT_DECL_VALUEARRAY_(35);
404 IIUT_DECL_VALUEARRAY_(36);
405 IIUT_DECL_VALUEARRAY_(37);
406 IIUT_DECL_VALUEARRAY_(38);
407 IIUT_DECL_VALUEARRAY_(39);
408 IIUT_DECL_VALUEARRAY_(40);
409 IIUT_DECL_VALUEARRAY_(41);
410 IIUT_DECL_VALUEARRAY_(42);
411 IIUT_DECL_VALUEARRAY_(43);
412 IIUT_DECL_VALUEARRAY_(44);
413 IIUT_DECL_VALUEARRAY_(45);
414 IIUT_DECL_VALUEARRAY_(46);
415 IIUT_DECL_VALUEARRAY_(47);
416 IIUT_DECL_VALUEARRAY_(48);
417 IIUT_DECL_VALUEARRAY_(49);
418 IIUT_DECL_VALUEARRAY_(50);
419 
420 #undef IIUT_DECL_VALUEARRAY_CONSTRUCT_
421 #undef IIUT_DECL_VALUEARRAY_STATICCAST_
422 #undef IIUT_DECL_VALUEARRAY_VARIABLE_
423 #undef IIUT_DECL_VALUEARRAY_CONCAT_
424 #undef IIUT_DECL_VALUEARRAY_
425 
426 #endif
427 
428 #if IUTEST_HAS_COMBINE
429 
430 #if IUTEST_HAS_VARIADIC_COMBINE
431 
432 template<typename... Args>
433 class iuCartesianProductGenerator : public iuIParamGenerator< tuples::tuple<Args...> >
434 {
435  typedef tuples::tuple< iuParamGenerator<Args>... > _MyTuple;
436  static const int kCount = sizeof...(Args);
437 
438  struct begin_func
439  {
440  template<typename T>
441  void operator ()(int, T& value) const { value.Begin(); }
442  };
443 
444  template<int index, int end, typename Tuple>
445  bool is_end_foreach(Tuple& t
446  , typename detail::enable_if<index != end, void>::type*& = detail::enabler::value ) const
447  {
448  const bool b = tuples::get<index>(t).IsEnd();
449  return b && is_end_foreach<index+1, end>(t);
450  }
451  template<int index, int end, typename Tuple>
452  bool is_end_foreach(Tuple&
453  , typename detail::enable_if<index == end, void>::type*& = detail::enabler::value ) const
454  {
455  return true;
456  }
457 
458  template<int index, int end, typename Tuple>
459  void next_foreach(Tuple& t
460  , typename detail::enable_if<index != end, void>::type*& = detail::enabler::value )
461  {
462  next_foreach<index+1, end>(t);
463  if( is_end_foreach<index+1, end>(t) )
464  {
465  tuples::get<index>(t).Next();
466  if( !tuples::get<index>(t).IsEnd() )
467  {
468  tuples::tuple_foreach<index + 1>(t, begin_func());
469  }
470  }
471  }
472  template<int index, int end, typename Tuple>
473  void next_foreach(Tuple&
474  , typename detail::enable_if<index == end, void>::type*& = detail::enabler::value )
475  {
476  }
477 
478  template<int index, int end, typename T1, typename ...TArgs>
479  tuples::tuple<T1, TArgs...> current_foreach(
480  typename detail::enable_if<index != end-1, void>::type*& = detail::enabler::value ) const
481  {
482  return ::std::tuple_cat( tuples::tuple<T1>(tuples::get<index>(v).GetCurrent())
483  , current_foreach<index+1, end, TArgs...>());
484  }
485  template<int index, int end, typename T1, typename ...TArgs>
486  tuples::tuple<T1> current_foreach(
487  typename detail::enable_if<index == end-1, void>::type*& = detail::enabler::value ) const
488  {
489  return tuples::tuple<T1>(tuples::get<index>(v).GetCurrent());
490  }
491 
492 public:
493  typedef tuples::tuple<Args...> ParamType;
494 public:
495  iuCartesianProductGenerator() {}
496 
497 public:
498  virtual void Begin() IUTEST_CXX_OVERRIDE
499  {
500  tuples::tuple_foreach(v, begin_func());
501  }
502  virtual void Next() IUTEST_CXX_OVERRIDE
503  {
504  if( !IsEnd() )
505  {
506  next_foreach<0, kCount>(v);
507  }
508  }
509  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
510  {
511  return is_end_foreach<0, kCount>(v);
512  }
513  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
514  {
515  return current_foreach<0, kCount, Args...>();
516  }
517 
518  _MyTuple& generators() { return v; }
519 private:
520  _MyTuple v;
521 };
522 
523 template<typename... Generator>
524 class iuCartesianProductHolder
525 {
526  typedef iuCartesianProductHolder<Generator...> _Myt;
527  typedef tuples::tuple<const Generator...> _MyTuple;
528 
529 public:
530  explicit iuCartesianProductHolder(const Generator&... generators)
531  : v(generators...) {}
532 
533 public:
534  template<typename... Args>
535  operator iuIParamGenerator< tuples::tuple<Args...> >* () const
536  {
537  iuCartesianProductGenerator<Args...>* p = new iuCartesianProductGenerator<Args...>();
538  tuples::tuple_cast_copy(p->generators(), v);
539  return p;
540  }
541 
542 public:
543 #if IUTEST_HAS_CONCAT
544  template<typename Other>
545  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
546  {
547  return iuConcatParamHolder<_Myt, Other>(*this, g);
548  }
549 #endif
550 
551 private:
552  _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION;
553 private:
554  _MyTuple v;
555 };
556 
557 
558 #else
559 
560 template<typename Generator1, typename Generator2, typename ParamType>
561 class iuICartesianProductGeneratorBase : public iuIParamGenerator< ParamType >
562 {
563 public:
564  iuICartesianProductGeneratorBase(const Generator1& g1, const Generator2& g2)
565  : m_g1(g1), m_g2(g2)
566  {}
567 public:
568  virtual void Begin() IUTEST_CXX_OVERRIDE
569  {
570  m_g1.Begin();
571  m_g2.Begin();
572  }
573  virtual void Next() IUTEST_CXX_OVERRIDE
574  {
575  if( m_g2.IsEnd() )
576  {
577  return;
578  }
579  m_g2.Next();
580  if( m_g2.IsEnd() )
581  {
582  m_g1.Next();
583  if( !m_g1.IsEnd() )
584  {
585  m_g2.Begin();
586  }
587  }
588  }
589  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
590  {
591  return m_g1.IsEnd() && m_g2.IsEnd();
592  }
593 
594 protected:
595  Generator1 m_g1;
596  Generator2 m_g2;
597 };
598 
599 template<typename T1, typename T2>
600 class iuCartesianProductGenerator2
601  : public iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuParamGenerator<T2>, tuples::tuple<T1, T2> >
602 {
603  typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuParamGenerator<T2>, tuples::tuple<T1, T2> > _Mybase;
604  typedef iuParamGenerator<T1> Generator1;
605  typedef iuParamGenerator<T2> Generator2;
606 public:
607  typedef tuples::tuple<T1, T2> ParamType;
608 
609 public:
610  iuCartesianProductGenerator2(const Generator1 &g1, const Generator2 &g2)
611  : _Mybase(g1, g2)
612  {}
613 
614 public:
615  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
616  {
617  return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
618  }
619 };
620 
621 /*
622 template<typename T1, typename T2, typename T3>
623 class iuCartesianProductGenerator3 : public iuICartesianProductGeneratorBase<iuParamGenerator<T1>
624  , iuCartesianProductGenerator2<T2, T3>
625  , tuples::tuple<T1, T2, T3> >
626 {
627  typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuCartesianProductGenerator2<T2, T3>, tuples::tuple<T1, T2, T3> > _Mybase;
628  typedef iuParamGenerator<T1> Generator1;
629  typedef iuParamGenerator<T2> Generator2;
630  typedef iuParamGenerator<T3> Generator3;
631 public:
632  typedef tuples::tuple<T1, T2, T3> ParamType;
633 public:
634  iuCartesianProductGenerator3(const Generator1& g1, const Generator2& g2, const Generator3& g3)
635  : _Mybase(g1, iuCartesianProductGenerator2<T2, T3>(g2, g3))
636  {}
637 
638 public:
639  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
640  {
641  tuples::tuple<T2, T3> param(this->m_g2.GetCurrent());
642  return ParamType(this->m_g1.GetCurrent(), tuples::get<0>(param), tuples::get<1>(param) );
643  }
644 };
645 */
646 
651 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_(i, p1, p2) \
652  typedef iuParamGenerator<IUTEST_PP_CAT(p1, i)> IUTEST_PP_CAT(p2, i);
653 
654 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_(i, param) \
655  tuples::get<i>(param)
656 
657 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) \
658  iuICartesianProductGeneratorBase< iuParamGenerator<T0> \
659  , IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))< \
660  IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) > \
661  , tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >
662 
663 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(n) \
664  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
665  class IUTEST_PP_CAT(iuCartesianProductGenerator, n) \
666  : public IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) { \
667  typedef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) _Mybase; \
668  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_, T, Generator) \
669  public: \
670  typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType; \
671  IUTEST_PP_CAT(iuCartesianProductGenerator, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
672  : _Mybase(g0, IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))< \
673  IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T)> \
674  ( IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), g) ) ) {} \
675  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE { \
676  tuples::tuple< IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) > \
677  params(this->m_g2.GetCurrent()); \
678  return ParamType(this->m_g1.GetCurrent(), IUTEST_PP_ENUM(IUTEST_PP_DEC(n) \
679  , IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_, params) ); \
680  } \
681  }
682 
687 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(3);
688 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(4);
689 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(5);
690 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(6);
691 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(7);
692 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(8);
693 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(9);
694 
695 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_
696 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_
697 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_
698 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_
699 
700 // iuCartesianProductHolder
701 
702 /*
703 template<typename Generator1, typename Generator2>
704 class iuCartesianProductHolder2
705 {
706  typedef iuCartesianProductHolder2<Generator1, Generator2> _Myt;
707 public:
708  iuCartesianProductHolder2(const Generator1& g1, const Generator2& g2)
709  : m_g1(g1), m_g2(g2) {}
710 
711 public:
712  template<typename T1, typename T2>
713  operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
714  {
715  return new iuCartesianProductGenerator2<T1, T2>(
716  static_cast< iuIParamGenerator<T1>* >(m_g1)
717  , static_cast< iuIParamGenerator<T2>* >(m_g2)
718  );
719  }
720 
721 public:
722  template<typename Other>
723  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
724  {
725  return iuConcatParamHolder<_Myt, Other>(*this, g);
726  }
727 
728 private:
729  _Myt& operator = (const _Myt&);
730 private:
731  const Generator1 m_g1;
732  const Generator2 m_g2;
733 };
734 */
735 
740 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_(i, p1, p2) IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
741 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_(i, p1, p2) \
742  static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
743 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_(i, p1, p2) IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
744 #if IUTEST_HAS_CONCAT
745 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_() \
746  template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
747  return iuConcatParamHolder<_Myt, Other>(*this, g); }
748 #else
749 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_()
750 #endif
751 
752 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(n) \
753  template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) > \
754  class IUTEST_PP_CAT(iuCartesianProductHolder, n) { \
755  typedef IUTEST_PP_CAT(iuCartesianProductHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt; \
756  public: \
757  IUTEST_PP_CAT(iuCartesianProductHolder, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
758  : IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_, m_g, g) {} \
759  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
760  operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* () const { \
761  return new IUTEST_PP_CAT(iuCartesianProductGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >( \
762  IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_, T, m_g) ); \
763  } \
764  IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_() \
765  private: _Myt& operator = (const _Myt&); \
766  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_, const Generator, m_g) \
767  }
768 
773 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(2);
774 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(3);
775 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(4);
776 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(5);
777 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(6);
778 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(7);
779 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(8);
780 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(9);
781 
782 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_
783 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_
784 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_
785 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_
786 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_
787 
788 #endif
789 
790 #endif
791 
792 #if IUTEST_HAS_PAIRWISE
793 
794 class iuPairwiseGeneratorBase
795 {
796 protected:
797  template<int N>
798  struct ParamIndexes
799  {
800  int index[N];
801  ParamIndexes() { for( int i=0; i < N; ++i ) index[i] = -1; }
802  };
803 
804 private:
805  struct PairInfo {
806  PairInfo(int r1, int r2, int i1, int i2)
807  : raw1(r1), raw2(r2), idx1(i1), idx2(i2) {}
808  int raw1, raw2; // 列のペア
809  int idx1, idx2; // インデックスのペア
810  };
811 protected:
812  template<typename T1>
813  static void MakeParamVector( ::std::vector<T1>& list, iuParamGenerator<T1>& g1)
814  {
815  for( g1.Begin(); !g1.IsEnd(); g1.Next() )
816  {
817  list.push_back(g1.GetCurrent());
818  }
819  }
820 
821  template<typename T1, typename T2>
822  static void MakePairList( ::std::vector< ::std::pair<T1, T2> >& list
823  , iuParamGenerator<T1>& g1, iuParamGenerator<T2>& g2)
824  {
825  for( g1.Begin(); !g1.IsEnd(); g1.Next() )
826  {
827  T1 t1 = g1.GetCurrent();
828  for( g2.Begin(); !g2.IsEnd(); g2.Next() )
829  {
830 #if IUTEST_HAS_STD_EMPLACE
831  list.emplace_back(t1, g2.GetCurrent());
832 #else
833  list.push_back(::std::pair<T1, T2>(t1, g2.GetCurrent()));
834 #endif
835  }
836  }
837  }
838 
839  template<int N>
840  static void MakeIndexList( ::std::vector< ParamIndexes<N> >& list, int* count_list)
841  {
842  typedef typename ::std::vector< ParamIndexes<N> >::iterator list_iterator;
843  list.clear();
844 
845  // ペアを列挙
846  ::std::vector<PairInfo> pair_list;
847  for( int i=0; i < N; ++i )
848  {
849  int l = count_list[i];
850  for( int j=i+1; j < N; ++j )
851  {
852  int r = count_list[j];
853  for( int li=0; li < l; ++li )
854  {
855  for( int ri=0; ri < r; ++ri )
856  {
857 #if IUTEST_HAS_STD_EMPLACE
858  pair_list.emplace_back(i, j, li, ri);
859 #else
860  PairInfo info( i, j, li, ri );
861  pair_list.push_back(info);
862 #endif
863  }
864  }
865  }
866  }
867 
868  // シャッフル
869  iuRandom random;
870  unsigned int seed = TestEnv::get_random_seed();
871  if( seed != 0 )
872  {
873  random.init(seed);
874  }
875  random.shuffle(pair_list.begin(), pair_list.end());
876 
877  for( ::std::vector<PairInfo>::const_iterator it=pair_list.begin(); it != pair_list.end(); ++it )
878  {
879  const PairInfo& pair_info = *it;
880  list_iterator find = Find(list, pair_info, list.begin());
881  if( find == list.end() )
882  {
883  find = FindFree(list, pair_info, list.begin());
884  if( find == list.end() )
885  {
886  // 空きが無いので作る
887  ParamIndexes<N> params;
888  params.index[pair_info.raw1] = pair_info.idx1;
889  params.index[pair_info.raw2] = pair_info.idx2;
890  list.push_back(params);
891  }
892  else
893  {
894  // 埋める
895  ParamIndexes<N>& params = *find;
896  params.index[pair_info.raw1] = pair_info.idx1;
897  params.index[pair_info.raw2] = pair_info.idx2;
898  }
899  }
900  }
901 
902  //for( list_iterator it=list.begin(), end=list.end(); it != end; ++it )
903  //{
904  // for( int i=0; i < N; ++i ) printf("%2d ", it->index[i]);
905  // printf("\n");
906  //}
907  }
908 
909  template<int N, typename Fn>
910  static int GetParamIndex(const ParamIndexes<N>& indexes, int raw, int count, Fn& func)
911  {
912  return indexes.index[raw] == -1 ? func(count)
913  : indexes.index[raw];
914  }
915 
916  template<int N, typename T>
917  static T GetParam(const ::std::vector<T>& params, const ParamIndexes<N>& indexes, int raw)
918  {
919  iuTypedRandom<int> rnd(TestEnv::genrand()());
920  const int index = GetParamIndex(indexes, raw, static_cast<int>(params.size()), rnd);
921  return params[index];
922  }
923 
924 private:
925  template<int N>
926  static typename ::std::vector< ParamIndexes<N> >::iterator Find( ::std::vector< ParamIndexes<N> >& list
927  , const PairInfo& pair_info, typename ::std::vector< ParamIndexes<N> >::iterator start)
928  {
929  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
930  for( iterator it = start, end=list.end(); it != end; ++it )
931  {
932  ParamIndexes<N>& indexes = *it;
933  if( indexes.index[pair_info.raw1] == pair_info.idx1
934  && indexes.index[pair_info.raw2] == pair_info.idx2 )
935  {
936  return it;
937  }
938  }
939  return list.end();
940  }
941 
942  template<int N>
943  static typename ::std::vector< ParamIndexes<N> >::iterator FindFree( ::std::vector< ParamIndexes<N> >& list
944  , const PairInfo& pair_info, typename ::std::vector< ParamIndexes<N> >::iterator start)
945  {
946  // 入れそうなとこを探す
947  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
948  iterator find = list.end();
949  UInt32 max_overlap = static_cast<UInt32>(-1);
950  for( iterator it = start, end=list.end(); it != end; ++it )
951  {
952  ParamIndexes<N>& indexes = *it;
953  int free_raw = -1;
954  int free_idx = -1;
955  if( indexes.index[pair_info.raw1] == -1 && indexes.index[pair_info.raw2] == pair_info.idx2 )
956  {
957  free_raw = pair_info.raw1;
958  free_idx = pair_info.idx1;
959  }
960  if( indexes.index[pair_info.raw2] == -1 && indexes.index[pair_info.raw1] == pair_info.idx1 )
961  {
962  free_raw = pair_info.raw2;
963  free_idx = pair_info.idx2;
964  }
965  if( free_raw != -1 )
966  {
967  // 仮に入ったとして重複がないか調べる
968  UInt32 overlap = 0;
969  for( int i=0; i < N; ++i )
970  {
971  if( indexes.index[i] == -1 || i == free_raw )
972  {
973  continue;
974  }
975  PairInfo tmp(i, free_raw, indexes.index[i], free_idx);
976  iterator it2 = Find(list, tmp, list.begin());
977  while(it2 != end)
978  {
979  ++overlap;
980  ++it2;
981  it2 = Find(list, tmp, it2);
982  }
983  }
984  if( overlap == 0 )
985  {
986  return it;
987  }
988  if( find == list.end()
989  || (overlap < max_overlap) )
990  {
991  find = it;
992  max_overlap = overlap;
993  }
994  }
995  }
996  if( find != list.end() )
997  {
998  return find;
999  }
1000 
1001  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
1002  for( iterator it = start, end=list.end(); it != end; ++it )
1003  {
1004  ParamIndexes<N>& indexes = *it;
1005  if( indexes.index[pair_info.raw1] == -1 && indexes.index[pair_info.raw2] == -1 )
1006  {
1007  return it;
1008  }
1009  }
1010  return list.end();
1011  }
1012 };
1013 
1014 #if IUTEST_HAS_VARIADIC_PAIRWISE
1015 
1016 template<typename... Args>
1017 class iuPairwiseGenerator : public iuPairwiseGeneratorBase
1018 {
1019  typedef tuples::tuple< Args... > ParamType;
1020  typedef tuples::tuple< iuParamGenerator<Args>... > GeneratorTuple;
1021  static const int kRAW_COUNT = sizeof...(Args);
1022 
1023  typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;
1024  typedef ::std::vector< _MyParamIndexes > ParamIndexesList;
1025 
1026  typedef tuples::tuple< ::std::vector<Args>... > ParamsTuple;
1027 
1028 public:
1029  static iuIParamGenerator< ParamType >* Create(GeneratorTuple& generators)
1030  {
1031  ParamIndexesList list;
1032  ParamVecotrs param_vectors(generators);
1033 
1034  MakeIndexList(list, param_vectors.count_list);
1035 
1036  ::std::vector<ParamType> params;
1037  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
1038  {
1039  const _MyParamIndexes& indexes = *it;
1040  params.push_back(MakeParam<0, Args...>(param_vectors.params_list, indexes));
1041  }
1042 
1043  return new iuValuesInParamsGenerator< ParamType >(params);
1044  }
1045 private:
1046  template<int N, typename T1, typename... TArgs>
1047  static tuples::tuple<T1, TArgs...> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
1048  , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1049  {
1050  return ::std::tuple_cat( tuples::tuple<T1>(GetParam(tuples::get<N>(list), indexes, N))
1051  , MakeParam<N+1, TArgs...>(list, indexes) );
1052  }
1053  template<int N, typename T1, typename... TArgs>
1054  static tuples::tuple<T1> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
1055  , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1056  {
1057  return tuples::tuple<T1>( GetParam( tuples::get<N>(list), indexes, N) );
1058  }
1059 
1060  struct ParamVecotrs
1061  {
1062  ParamsTuple params_list;
1063  int count_list[kRAW_COUNT];
1064 
1065  template<int N>
1066  void MakeParamVecotrs(GeneratorTuple& generators
1067  , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1068  {
1069  MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
1070  count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
1071  MakeParamVecotrs<N+1>(generators);
1072  }
1073  template<int N>
1074  void MakeParamVecotrs(GeneratorTuple& generators
1075  , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1076  {
1077  MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
1078  count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
1079  }
1080 
1081  explicit ParamVecotrs(GeneratorTuple& generators)
1082  {
1083  MakeParamVecotrs<0>(generators);
1084  }
1085  };
1086 };
1087 
1088 template<typename... Generator>
1089 class iuPairwiseHolder
1090 {
1091  typedef iuPairwiseHolder<Generator...> _Myt;
1092  typedef tuples::tuple<const Generator...> _MyTuple;
1093 
1094 public:
1095  explicit iuPairwiseHolder(const Generator&... generators)
1096  : v(generators...) {}
1097 
1098 public:
1099  template<typename... Args>
1100  operator iuIParamGenerator< tuples::tuple<Args...> >* () const
1101  {
1102  tuples::tuple< iuParamGenerator<Args>... > generators;
1103  tuples::tuple_cast_copy(generators, v);
1104  return iuPairwiseGenerator<Args...>::Create(generators);
1105  }
1106 
1107 public:
1108 #if IUTEST_HAS_CONCAT
1109  template<typename Other>
1110  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1111  {
1112  return iuConcatParamHolder<_Myt, Other>(*this, g);
1113  }
1114 #endif
1115 
1116 private:
1117  _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION;
1118 private:
1119  _MyTuple v;
1120 };
1121 
1122 #else
1123 
1124 template<typename T1, typename T2>
1125 class iuPairwiseGenerator2 : public iuIParamGenerator< tuples::tuple<T1, T2> >
1126 {
1127  typedef iuParamGenerator<T1> Generator1;
1128  typedef iuParamGenerator<T2> Generator2;
1129 public:
1130  typedef tuples::tuple<T1, T2> ParamType;
1131 
1132 public:
1133  iuPairwiseGenerator2(const Generator1& g1, const Generator2& g2)
1134  : m_g1(g1), m_g2(g2)
1135  {}
1136 
1137  static iuIParamGenerator< ParamType >* Create(const Generator1& g1, const Generator2& g2)
1138  {
1139  return new iuPairwiseGenerator2<T1, T2>(g1, g2);
1140  }
1141 public:
1142  virtual void Begin() IUTEST_CXX_OVERRIDE
1143  {
1144  m_g1.Begin();
1145  m_g2.Begin();
1146  }
1147  virtual void Next() IUTEST_CXX_OVERRIDE
1148  {
1149  if( m_g2.IsEnd() )
1150  {
1151  return;
1152  }
1153  m_g2.Next();
1154  if( m_g2.IsEnd() )
1155  {
1156  m_g1.Next();
1157  if( !m_g1.IsEnd() )
1158  {
1159  m_g2.Begin();
1160  }
1161  }
1162  }
1163  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
1164  {
1165  return m_g1.IsEnd() && m_g2.IsEnd();
1166  }
1167  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
1168  {
1169  return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
1170  }
1171 private:
1172  Generator1 m_g1;
1173  Generator2 m_g2;
1174 };
1175 
1176 /*
1177 template<typename T1, typename T2, typename T3>
1178 class iuPairwiseGenerator3 : public iuPairwiseGeneratorBase
1179 {
1180  typedef iuParamGenerator<T1> Generator1;
1181  typedef iuParamGenerator<T2> Generator2;
1182  typedef iuParamGenerator<T3> Generator3;
1183 
1184  static const int kRAW_COUNT = 3;
1185  typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;
1186  typedef ::std::vector< _MyParamIndexes > ParamIndexesList;
1187 
1188 public:
1189  typedef tuples::tuple<T1, T2, T3> ParamType;
1190 public:
1191  static iuIParamGenerator< ParamType >* Create(Generator1 g1, Generator2 g2, Generator3 g3)
1192  {
1193  ParamIndexesList list;
1194  ::std::vector<T1> params1;
1195  ::std::vector<T2> params2;
1196  ::std::vector<T3> params3;
1197 
1198  MakeParamVector(params1, g1);
1199  MakeParamVector(params2, g2);
1200  MakeParamVector(params3, g3);
1201 
1202  int count_list[] = {
1203  static_cast<int>(params1.size())
1204  , static_cast<int>(params2.size())
1205  , static_cast<int>(params3.size())
1206  };
1207  MakeIndexList(list, count_list);
1208 
1209  ::std::vector<ParamType> params;
1210 
1211  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
1212  {
1213  const _MyParamIndexes& indexes = *it;
1214  params.push_back( ParamType(
1215  GetParam(params1, indexes, 0)
1216  , GetParam(params2, indexes, 1)
1217  , GetParam(params3, indexes, 2)
1218  ) );
1219  }
1220 
1221  return new iuValuesInParamsGenerator< ParamType >(params);
1222  }
1223 };
1224 */
1225 
1230 #define IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_(i, p1, p2) \
1231  p1<IUTEST_PP_CAT(T, i)> IUTEST_PP_CAT(p2, i);
1232 #define IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_(i, p1, p2) \
1233  MakeParamVector( IUTEST_PP_CAT(p1, i), IUTEST_PP_CAT(p2, i) );
1234 #define IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_(i, param) \
1235  static_cast<int>( IUTEST_PP_CAT(param, i).size() )
1236 #define IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_(i, param) \
1237  GetParam( IUTEST_PP_CAT(param, i), indexes, i)
1238 
1239 #define IIUT_DECL_PAIRWISE_GENERATOR_(n) \
1240  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
1241  class IUTEST_PP_CAT(iuPairwiseGenerator, n) : public iuPairwiseGeneratorBase { \
1242  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, typedef iuParamGenerator, Generator) \
1243  typedef ParamIndexes<n> _MyParamIndexes; \
1244  typedef ::std::vector< _MyParamIndexes > ParamIndexesList; \
1245  public: typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType; \
1246  static iuIParamGenerator< ParamType >* Create( \
1247  IUTEST_PP_ENUM_BINARY_PARAMS(n, Generator, g) ) { \
1248  ParamIndexesList list; \
1249  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, ::std::vector, params) \
1250  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_, params, g) \
1251  int count_list[] = { IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_, params) }; \
1252  MakeIndexList(list, count_list); \
1253  ::std::vector<ParamType> params; \
1254  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it ) { \
1255  const _MyParamIndexes& indexes = *it; \
1256  params.push_back( ParamType( IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_, params) ) ); \
1257  } \
1258  return new iuValuesInParamsGenerator< ParamType >(params); \
1259  } \
1260  }
1261 
1266 IIUT_DECL_PAIRWISE_GENERATOR_(3);
1267 IIUT_DECL_PAIRWISE_GENERATOR_(4);
1268 IIUT_DECL_PAIRWISE_GENERATOR_(5);
1269 IIUT_DECL_PAIRWISE_GENERATOR_(6);
1270 IIUT_DECL_PAIRWISE_GENERATOR_(7);
1271 IIUT_DECL_PAIRWISE_GENERATOR_(8);
1272 IIUT_DECL_PAIRWISE_GENERATOR_(9);
1273 
1274 #undef IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_
1275 #undef IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_
1276 #undef IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_
1277 #undef IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_
1278 #undef IIUT_DECL_PAIRWISE_GENERATOR_
1279 
1280 /*
1281 template<typename Generator1, typename Generator2>
1282 class iuPairwiseHolder2
1283 {
1284  typedef iuPairwiseHolder2<Generator1, Generator2> _Myt;
1285 public:
1286  iuPairwiseHolder2(const Generator1& g1, const Generator2& g2)
1287  : m_g1(g1), m_g2(g2) {}
1288 
1289 public:
1290  template<typename T1, typename T2>
1291  operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
1292  {
1293  return iuPairwiseGenerator2<T1, T2>::Create(
1294  static_cast< iuIParamGenerator<T1>* >(m_g1)
1295  , static_cast< iuIParamGenerator<T2>* >(m_g2)
1296  );
1297  }
1298 
1299 public:
1300  template<typename Other>
1301  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1302  {
1303  return iuConcatParamHolder<_Myt, Other>(*this, g);
1304  }
1305 
1306 private:
1307  _Myt& operator = (const _Myt&);
1308 private:
1309  const Generator1 m_g1;
1310  const Generator2 m_g2;
1311 };
1312 */
1313 
1314 #define IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_(i, p1, p2) IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
1315 #define IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_(i, p1, p2) \
1316  static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
1317 #define IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_(i, p1, p2) IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
1318 #if IUTEST_HAS_CONCAT
1319 # define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_() \
1320  template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
1321  return iuConcatParamHolder<_Myt, Other>(*this, g); }
1322 #else
1323 # define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_()
1324 #endif
1325 
1326 #define IIUT_DECL_PAIRWISE_HOLDER_(n) \
1327  template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) > \
1328  class IUTEST_PP_CAT(iuPairwiseHolder, n) { \
1329  typedef IUTEST_PP_CAT(iuPairwiseHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt; \
1330  public: IUTEST_PP_CAT(iuPairwiseHolder, n)( \
1331  IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
1332  : IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_, m_g, g) {} \
1333  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
1334  operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* () const { \
1335  return IUTEST_PP_CAT(iuPairwiseGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >::Create( \
1336  IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_, T, m_g) ); \
1337  } \
1338  IIUT_DECL_PAIRWISE_HOLDER_CONCAT_() \
1339  private: _Myt& operator = (const _Myt&); \
1340  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_, const Generator, m_g) \
1341  }
1342 
1343 IIUT_DECL_PAIRWISE_HOLDER_(2);
1344 IIUT_DECL_PAIRWISE_HOLDER_(3);
1345 IIUT_DECL_PAIRWISE_HOLDER_(4);
1346 IIUT_DECL_PAIRWISE_HOLDER_(5);
1347 IIUT_DECL_PAIRWISE_HOLDER_(6);
1348 IIUT_DECL_PAIRWISE_HOLDER_(7);
1349 IIUT_DECL_PAIRWISE_HOLDER_(8);
1350 IIUT_DECL_PAIRWISE_HOLDER_(9);
1351 
1352 #undef IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_
1353 #undef IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_
1354 #undef IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_
1355 #undef IIUT_DECL_PAIRWISE_HOLDER_CONCAT_
1356 #undef IIUT_DECL_PAIRWISE_HOLDER_
1357 
1358 #endif
1359 
1360 #endif
1361 
1362 #if IUTEST_HAS_VALUESGEN
1363 
1368 template<typename StdGenerator>
1369 class iuValuesParamsGeneratorHolder
1370 {
1371  typedef iuValuesParamsGeneratorHolder<StdGenerator> _Myt;
1372 public:
1373  iuValuesParamsGeneratorHolder(size_t num, const StdGenerator& g)
1374  : m_num(num), m_g(g)
1375  {}
1376 public:
1377  template<typename T>
1378  operator iuIParamGenerator<T>* () const
1379  {
1380  ::std::vector<T> params(m_num);
1381  ::std::generate(params.begin(), params.end(), m_g);
1382  return new iuValuesInParamsGenerator<T>( params );
1383  }
1384 
1385 public:
1386 #if IUTEST_HAS_CONCAT
1387  template<typename Other>
1388  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1389  {
1390  return iuConcatParamHolder<_Myt, Other>(*this, g);
1391  }
1392 #endif
1393 
1394 private:
1395  size_t m_num;
1396  StdGenerator m_g;
1397 };
1398 
1402 template<typename T, typename F>
1403 class iuRandomFilterParamGenerator
1404 {
1405  typedef T type;
1406 public:
1407  iuRandomFilterParamGenerator(const F& fn, unsigned int seed)
1408  : m_fn(fn), m_rnd(seed) {}
1409 
1410  type operator ()()
1411  {
1412  type val = m_rnd.genrand();
1413  for( ; !(m_fn)(val); val = m_rnd.genrand() ) {}
1414  return val;
1415  }
1416 private:
1417  F m_fn;
1418  iuTypedRandom<type> m_rnd;
1419 };
1420 
1421 #endif
1422 
1423 #if IUTEST_HAS_RANDOMVALUES
1424 
1428 class iuRandomParamsHolder
1429 {
1430 public:
1431  explicit iuRandomParamsHolder(size_t num, unsigned int seed=0) IUTEST_CXX_NOEXCEPT_SPEC
1432  : m_num(num), m_seed(seed) {}
1433 public:
1434  template<typename T>
1435  operator iuIParamGenerator<T>* () const
1436  {
1437  unsigned int seed = m_seed;
1438  if( seed == 0 )
1439  {
1440  seed = GetIndefiniteValue();
1441  }
1442  iuValuesParamsGeneratorHolder< iuTypedRandom<T> > gen( m_num, iuTypedRandom<T>(seed) );
1443  return gen;
1444  }
1445 
1446 public:
1447 #if IUTEST_HAS_CONCAT
1448  template<typename Other>
1449  iuConcatParamHolder<iuRandomParamsHolder, Other> operator + (const Other& g) const
1450  {
1451  return iuConcatParamHolder<iuRandomParamsHolder, Other>(*this, g);
1452  }
1453 #endif
1454 
1455 private:
1456  size_t m_num;
1457  unsigned int m_seed;
1458 };
1459 
1460 #endif
1461 
1462 } // end of namespace detail
1463 } // end of namespace iutest
1464 
1465 #endif
1466 
1467 #endif // INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_
iutest_config.hpp
iris unit test config
IUTEST_CXX_NOEXCEPT_SPEC
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:734
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
IUTEST_CXX_DELETED_FUNCTION
#define IUTEST_CXX_DELETED_FUNCTION
delete function
Definition: iutest_compiler.hpp:371
IUTEST_CXX_OVERRIDE
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:670
iutest::UInt32
detail::type_fit_t< 4 >::UInt UInt32
32 bit 符号なし整数型
Definition: iutest_defs.hpp:424