iutest  1.17.99.14
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 IUTEST_CXX_FINAL : 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 IUTEST_CXX_FINAL : 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 IUTEST_CXX_FINAL : 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
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  }
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 IUTEST_CXX_FINAL : 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  iuCartesianProductHolder(const iuCartesianProductHolder& rhs)
531  : v(rhs.v)
532  {
533  }
534  explicit iuCartesianProductHolder(const Generator&... generators)
535  : v(generators...) {}
536 
537 public:
538  template<typename... Args>
539  operator iuIParamGenerator< tuples::tuple<Args...> >* () const
540  {
541  iuCartesianProductGenerator<Args...>* p = new iuCartesianProductGenerator<Args...>();
542  tuples::tuple_cast_copy(p->generators(), v);
543  return p;
544  }
545 
546 public:
547 #if IUTEST_HAS_CONCAT
548  template<typename Other>
549  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
550  {
551  return iuConcatParamHolder<_Myt, Other>(*this, g);
552  }
553 #endif
554 
555 private:
556  _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION;
557 private:
558  _MyTuple v;
559 };
560 
561 
562 #else
563 
564 template<typename Generator1, typename Generator2, typename ParamType>
565 class iuICartesianProductGeneratorBase : public iuIParamGenerator< ParamType >
566 {
567 public:
568  iuICartesianProductGeneratorBase(const Generator1& g1, const Generator2& g2)
569  : m_g1(g1), m_g2(g2)
570  {}
571 public:
572  virtual void Begin() IUTEST_CXX_OVERRIDE
573  {
574  m_g1.Begin();
575  m_g2.Begin();
576  }
577  virtual void Next() IUTEST_CXX_OVERRIDE
578  {
579  if( m_g2.IsEnd() )
580  {
581  return;
582  }
583  m_g2.Next();
584  if( m_g2.IsEnd() )
585  {
586  m_g1.Next();
587  if( !m_g1.IsEnd() )
588  {
589  m_g2.Begin();
590  }
591  }
592  }
593  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
594  {
595  return m_g1.IsEnd() && m_g2.IsEnd();
596  }
597 
598 protected:
599  Generator1 m_g1;
600  Generator2 m_g2;
601 };
602 
603 template<typename T1, typename T2>
604 class iuCartesianProductGenerator2
605  : public iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuParamGenerator<T2>, tuples::tuple<T1, T2> >
606 {
607  typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuParamGenerator<T2>, tuples::tuple<T1, T2> > _Mybase;
608  typedef iuParamGenerator<T1> Generator1;
609  typedef iuParamGenerator<T2> Generator2;
610 public:
611  typedef tuples::tuple<T1, T2> ParamType;
612 
613 public:
614  iuCartesianProductGenerator2(const Generator1 &g1, const Generator2 &g2)
615  : _Mybase(g1, g2)
616  {}
617 
618 public:
619  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
620  {
621  return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
622  }
623 };
624 
625 /*
626 template<typename T1, typename T2, typename T3>
627 class iuCartesianProductGenerator3 IUTEST_CXX_FINAL
628  : public iuICartesianProductGeneratorBase<iuParamGenerator<T1>
629  , iuCartesianProductGenerator2<T2, T3>
630  , tuples::tuple<T1, T2, T3> >
631 {
632  typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuCartesianProductGenerator2<T2, T3>, tuples::tuple<T1, T2, T3> > _Mybase;
633  typedef iuParamGenerator<T1> Generator1;
634  typedef iuParamGenerator<T2> Generator2;
635  typedef iuParamGenerator<T3> Generator3;
636 public:
637  typedef tuples::tuple<T1, T2, T3> ParamType;
638 public:
639  iuCartesianProductGenerator3(const Generator1& g1, const Generator2& g2, const Generator3& g3)
640  : _Mybase(g1, iuCartesianProductGenerator2<T2, T3>(g2, g3))
641  {}
642 
643 public:
644  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
645  {
646  tuples::tuple<T2, T3> param(this->m_g2.GetCurrent());
647  return ParamType(this->m_g1.GetCurrent(), tuples::get<0>(param), tuples::get<1>(param) );
648  }
649 };
650 */
651 
656 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_(i, p1, p2) \
657  typedef iuParamGenerator<IUTEST_PP_CAT(p1, i)> IUTEST_PP_CAT(p2, i);
658 
659 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_(i, param) \
660  tuples::get<i>(param)
661 
662 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) \
663  iuICartesianProductGeneratorBase< iuParamGenerator<T0> \
664  , IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))< \
665  IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) > \
666  , tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >
667 
668 #define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(n) \
669  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
670  class IUTEST_PP_CAT(iuCartesianProductGenerator, n) \
671  : public IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) { \
672  typedef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) _Mybase; \
673  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_, T, Generator) \
674  public: \
675  typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType; \
676  IUTEST_PP_CAT(iuCartesianProductGenerator, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
677  : _Mybase(g0, IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))< \
678  IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T)> \
679  ( IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), g) ) ) {} \
680  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE { \
681  tuples::tuple< IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) > \
682  params(this->m_g2.GetCurrent()); \
683  return ParamType(this->m_g1.GetCurrent(), IUTEST_PP_ENUM(IUTEST_PP_DEC(n) \
684  , IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_, params) ); \
685  } \
686  }
692 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(3);
693 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(4);
694 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(5);
695 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(6);
696 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(7);
697 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(8);
698 IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(9);
699 
700 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_
701 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_
702 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_
703 #undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_
704 
705 // iuCartesianProductHolder
706 
707 /*
708 template<typename Generator1, typename Generator2>
709 class iuCartesianProductHolder2
710 {
711  typedef iuCartesianProductHolder2<Generator1, Generator2> _Myt;
712 public:
713  iuCartesianProductHolder2(const Generator1& g1, const Generator2& g2)
714  : m_g1(g1), m_g2(g2) {}
715 
716 public:
717  template<typename T1, typename T2>
718  operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
719  {
720  return new iuCartesianProductGenerator2<T1, T2>(
721  static_cast< iuIParamGenerator<T1>* >(m_g1)
722  , static_cast< iuIParamGenerator<T2>* >(m_g2)
723  );
724  }
725 
726 public:
727  template<typename Other>
728  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
729  {
730  return iuConcatParamHolder<_Myt, Other>(*this, g);
731  }
732 
733 private:
734  _Myt& operator = (const _Myt&);
735 private:
736  const Generator1 m_g1;
737  const Generator2 m_g2;
738 };
739 */
740 
745 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_(i, p1, p2) IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
746 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_(i, p1, p2) \
747  static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
748 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_(i, p1, p2) IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
749 #if IUTEST_HAS_CONCAT
750 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_() \
751  template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
752  return iuConcatParamHolder<_Myt, Other>(*this, g); }
753 #else
754 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_()
755 #endif
756 
757 #define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(n) \
758  template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) > \
759  class IUTEST_PP_CAT(iuCartesianProductHolder, n) { \
760  typedef IUTEST_PP_CAT(iuCartesianProductHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt; \
761  public: \
762  IUTEST_PP_CAT(iuCartesianProductHolder, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
763  : IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_, m_g, g) {} \
764  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
765  operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* () const { \
766  return new IUTEST_PP_CAT(iuCartesianProductGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >( \
767  IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_, T, m_g) ); \
768  } \
769  IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_() \
770  private: _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION; \
771  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_, const Generator, m_g) \
772  }
773 
778 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(2);
779 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(3);
780 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(4);
781 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(5);
782 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(6);
783 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(7);
784 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(8);
785 IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(9);
786 
787 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_
788 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_
789 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_
790 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_
791 #undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_
792 
793 #endif
794 
795 #endif
796 
797 #if IUTEST_HAS_PAIRWISE
798 
799 class iuPairwiseGeneratorBase
800 {
801 protected:
802  template<int N>
803  struct ParamIndexes
804  {
805  int index[N];
806  ParamIndexes() { for( int i=0; i < N; ++i ) index[i] = -1; }
807  };
808 
809 private:
810  struct PairInfo {
811  PairInfo(int r1, int r2, int i1, int i2)
812  : raw1(r1), raw2(r2), idx1(i1), idx2(i2) {}
813  int raw1, raw2; // 列のペア
814  int idx1, idx2; // インデックスのペア
815  };
816 protected:
817  template<typename T1>
818  static void MakeParamVector( ::std::vector<T1>& list, iuParamGenerator<T1>& g1)
819  {
820  for( g1.Begin(); !g1.IsEnd(); g1.Next() )
821  {
822  list.push_back(g1.GetCurrent());
823  }
824  }
825 
826  template<typename T1, typename T2>
827  static void MakePairList( ::std::vector< ::std::pair<T1, T2> >& list
828  , iuParamGenerator<T1>& g1, iuParamGenerator<T2>& g2)
829  {
830  for( g1.Begin(); !g1.IsEnd(); g1.Next() )
831  {
832  T1 t1 = g1.GetCurrent();
833  for( g2.Begin(); !g2.IsEnd(); g2.Next() )
834  {
835 #if IUTEST_HAS_STD_EMPLACE
836  list.emplace_back(t1, g2.GetCurrent());
837 #else
838  list.push_back(::std::pair<T1, T2>(t1, g2.GetCurrent()));
839 #endif
840  }
841  }
842  }
843 
844  template<int N>
845  static void MakeIndexList( ::std::vector< ParamIndexes<N> >& list, int* count_list)
846  {
847  typedef typename ::std::vector< ParamIndexes<N> >::iterator list_iterator;
848  list.clear();
849 
850  // ペアを列挙
851  ::std::vector<PairInfo> pair_list;
852  for( int i=0; i < N; ++i )
853  {
854  int l = count_list[i];
855  for( int j=i+1; j < N; ++j )
856  {
857  int r = count_list[j];
858  for( int li=0; li < l; ++li )
859  {
860  for( int ri=0; ri < r; ++ri )
861  {
862 #if IUTEST_HAS_STD_EMPLACE
863  pair_list.emplace_back(i, j, li, ri);
864 #else
865  PairInfo info( i, j, li, ri );
866  pair_list.push_back(info);
867 #endif
868  }
869  }
870  }
871  }
872 
873  // シャッフル
874  iuRandom random;
875  unsigned int seed = TestEnv::get_random_seed();
876  if( seed != 0 )
877  {
878  random.init(seed);
879  }
880  random.shuffle(pair_list.begin(), pair_list.end());
881 
882  for( ::std::vector<PairInfo>::const_iterator it=pair_list.begin(); it != pair_list.end(); ++it )
883  {
884  const PairInfo& pair_info = *it;
885  list_iterator find = Find(list, pair_info, list.begin());
886  if( find == list.end() )
887  {
888  find = FindFree(list, pair_info, list.begin());
889  if( find == list.end() )
890  {
891  // 空きが無いので作る
892  ParamIndexes<N> params;
893  params.index[pair_info.raw1] = pair_info.idx1;
894  params.index[pair_info.raw2] = pair_info.idx2;
895  list.push_back(params);
896  }
897  else
898  {
899  // 埋める
900  ParamIndexes<N>& params = *find;
901  params.index[pair_info.raw1] = pair_info.idx1;
902  params.index[pair_info.raw2] = pair_info.idx2;
903  }
904  }
905  }
906 
907  //for( list_iterator it=list.begin(), end=list.end(); it != end; ++it )
908  //{
909  // for( int i=0; i < N; ++i ) printf("%2d ", it->index[i]);
910  // printf("\n");
911  //}
912  }
913 
914  template<int N, typename Fn>
915  static int GetParamIndex(const ParamIndexes<N>& indexes, int raw, int count, Fn& func)
916  {
917  return indexes.index[raw] == -1 ? func(count)
918  : indexes.index[raw];
919  }
920 
921  template<int N, typename T>
922  static T GetParam(const ::std::vector<T>& params, const ParamIndexes<N>& indexes, int raw)
923  {
924  iuTypedRandom<int> rnd(TestEnv::genrand()());
925  const int index = GetParamIndex(indexes, raw, static_cast<int>(params.size()), rnd);
926  return params[index];
927  }
928 
929 private:
930  template<int N>
931  static typename ::std::vector< ParamIndexes<N> >::iterator Find( ::std::vector< ParamIndexes<N> >& list
932  , const PairInfo& pair_info, typename ::std::vector< ParamIndexes<N> >::iterator start)
933  {
934  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
935  for( iterator it = start, end=list.end(); it != end; ++it )
936  {
937  ParamIndexes<N>& indexes = *it;
938  if( indexes.index[pair_info.raw1] == pair_info.idx1
939  && indexes.index[pair_info.raw2] == pair_info.idx2 )
940  {
941  return it;
942  }
943  }
944  return list.end();
945  }
946 
947  template<int N>
948  static typename ::std::vector< ParamIndexes<N> >::iterator FindFree( ::std::vector< ParamIndexes<N> >& list
949  , const PairInfo& pair_info, typename ::std::vector< ParamIndexes<N> >::iterator start)
950  {
951  // 入れそうなとこを探す
952  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
953  iterator find = list.end();
954  UInt32 max_overlap = static_cast<UInt32>(-1);
955  for( iterator it = start, end=list.end(); it != end; ++it )
956  {
957  ParamIndexes<N>& indexes = *it;
958  int free_raw = -1;
959  int free_idx = -1;
960  if( indexes.index[pair_info.raw1] == -1 && indexes.index[pair_info.raw2] == pair_info.idx2 )
961  {
962  free_raw = pair_info.raw1;
963  free_idx = pair_info.idx1;
964  }
965  if( indexes.index[pair_info.raw2] == -1 && indexes.index[pair_info.raw1] == pair_info.idx1 )
966  {
967  free_raw = pair_info.raw2;
968  free_idx = pair_info.idx2;
969  }
970  if( free_raw != -1 )
971  {
972  // 仮に入ったとして重複がないか調べる
973  UInt32 overlap = 0;
974  for( int i=0; i < N; ++i )
975  {
976  if( indexes.index[i] == -1 || i == free_raw )
977  {
978  continue;
979  }
980  PairInfo tmp(i, free_raw, indexes.index[i], free_idx);
981  iterator it2 = Find(list, tmp, list.begin());
982  while(it2 != end)
983  {
984  ++overlap;
985  ++it2;
986  it2 = Find(list, tmp, it2);
987  }
988  }
989  if( overlap == 0 )
990  {
991  return it;
992  }
993  if( find == list.end()
994  || (overlap < max_overlap) )
995  {
996  find = it;
997  max_overlap = overlap;
998  }
999  }
1000  }
1001  if( find != list.end() )
1002  {
1003  return find;
1004  }
1005 
1006  typedef typename ::std::vector< ParamIndexes<N> >::iterator iterator;
1007  for( iterator it = start, end=list.end(); it != end; ++it )
1008  {
1009  ParamIndexes<N>& indexes = *it;
1010  if( indexes.index[pair_info.raw1] == -1 && indexes.index[pair_info.raw2] == -1 )
1011  {
1012  return it;
1013  }
1014  }
1015  return list.end();
1016  }
1017 };
1018 
1019 #if IUTEST_HAS_VARIADIC_PAIRWISE
1020 
1021 template<typename... Args>
1022 class iuPairwiseGenerator : public iuPairwiseGeneratorBase
1023 {
1024  typedef tuples::tuple< Args... > ParamType;
1025  typedef tuples::tuple< iuParamGenerator<Args>... > GeneratorTuple;
1026  static const int kRAW_COUNT = sizeof...(Args);
1027 
1028  typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;
1029  typedef ::std::vector< _MyParamIndexes > ParamIndexesList;
1030 
1031  typedef tuples::tuple< ::std::vector<Args>... > ParamsTuple;
1032 
1033 public:
1034  static iuIParamGenerator< ParamType >* Create(GeneratorTuple& generators)
1035  {
1036  ParamIndexesList list;
1037  ParamVecotrs param_vectors(generators);
1038 
1039  MakeIndexList(list, param_vectors.count_list);
1040 
1041  ::std::vector<ParamType> params;
1042  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
1043  {
1044  const _MyParamIndexes& indexes = *it;
1045  params.push_back(MakeParam<0, Args...>(param_vectors.params_list, indexes));
1046  }
1047 
1048  return new iuValuesInParamsGenerator< ParamType >(params);
1049  }
1050 private:
1051  template<int N, typename T1, typename... TArgs>
1052  static tuples::tuple<T1, TArgs...> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
1053  , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1054  {
1055  return ::std::tuple_cat( tuples::tuple<T1>(GetParam(tuples::get<N>(list), indexes, N))
1056  , MakeParam<N+1, TArgs...>(list, indexes) );
1057  }
1058  template<int N, typename T1, typename... TArgs>
1059  static tuples::tuple<T1> MakeParam(ParamsTuple& list, const _MyParamIndexes& indexes
1060  , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1061  {
1062  return tuples::tuple<T1>( GetParam( tuples::get<N>(list), indexes, N) );
1063  }
1064 
1065  struct ParamVecotrs
1066  {
1067  ParamsTuple params_list;
1068  int count_list[kRAW_COUNT];
1069 
1070  template<int N>
1071  void MakeParamVecotrs(GeneratorTuple& generators
1072  , typename detail::disable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1073  {
1074  MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
1075  count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
1076  MakeParamVecotrs<N+1>(generators);
1077  }
1078  template<int N>
1079  void MakeParamVecotrs(GeneratorTuple& generators
1080  , typename detail::enable_if<N == kRAW_COUNT -1, void>::type*& = detail::enabler::value)
1081  {
1082  MakeParamVector(tuples::get<N>(params_list), tuples::get<N>(generators));
1083  count_list[N] = static_cast<int>(tuples::get<N>(params_list).size());
1084  }
1085 
1086  explicit ParamVecotrs(GeneratorTuple& generators)
1087  {
1088  MakeParamVecotrs<0>(generators);
1089  }
1090  };
1091 };
1092 
1093 template<typename... Generator>
1094 class iuPairwiseHolder
1095 {
1096  typedef iuPairwiseHolder<Generator...> _Myt;
1097  typedef tuples::tuple<const Generator...> _MyTuple;
1098 
1099 public:
1100  iuPairwiseHolder(const iuPairwiseHolder& rhs)
1101  : v(rhs.v) {}
1102  explicit iuPairwiseHolder(const Generator&... generators)
1103  : v(generators...) {}
1104 
1105 public:
1106  template<typename... Args>
1107  operator iuIParamGenerator< tuples::tuple<Args...> >* () const
1108  {
1109  tuples::tuple< iuParamGenerator<Args>... > generators;
1110  tuples::tuple_cast_copy(generators, v);
1111  return iuPairwiseGenerator<Args...>::Create(generators);
1112  }
1113 
1114 public:
1115 #if IUTEST_HAS_CONCAT
1116  template<typename Other>
1117  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1118  {
1119  return iuConcatParamHolder<_Myt, Other>(*this, g);
1120  }
1121 #endif
1122 
1123 private:
1124  _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION;
1125 private:
1126  _MyTuple v;
1127 };
1128 
1129 #else
1130 
1131 template<typename T1, typename T2>
1132 class iuPairwiseGenerator2 IUTEST_CXX_FINAL : public iuIParamGenerator< tuples::tuple<T1, T2> >
1133 {
1134  typedef iuParamGenerator<T1> Generator1;
1135  typedef iuParamGenerator<T2> Generator2;
1136 public:
1137  typedef tuples::tuple<T1, T2> ParamType;
1138 
1139 public:
1140  iuPairwiseGenerator2(const Generator1& g1, const Generator2& g2)
1141  : m_g1(g1), m_g2(g2)
1142  {}
1143 
1144  static iuIParamGenerator< ParamType >* Create(const Generator1& g1, const Generator2& g2)
1145  {
1146  return new iuPairwiseGenerator2<T1, T2>(g1, g2);
1147  }
1148 public:
1149  virtual void Begin() IUTEST_CXX_OVERRIDE
1150  {
1151  m_g1.Begin();
1152  m_g2.Begin();
1153  }
1154  virtual void Next() IUTEST_CXX_OVERRIDE
1155  {
1156  if( m_g2.IsEnd() )
1157  {
1158  return;
1159  }
1160  m_g2.Next();
1161  if( m_g2.IsEnd() )
1162  {
1163  m_g1.Next();
1164  if( !m_g1.IsEnd() )
1165  {
1166  m_g2.Begin();
1167  }
1168  }
1169  }
1170  virtual bool IsEnd() const IUTEST_CXX_OVERRIDE
1171  {
1172  return m_g1.IsEnd() && m_g2.IsEnd();
1173  }
1174  virtual ParamType GetCurrent() const IUTEST_CXX_OVERRIDE
1175  {
1176  return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
1177  }
1178 private:
1179  Generator1 m_g1;
1180  Generator2 m_g2;
1181 };
1182 
1183 /*
1184 template<typename T1, typename T2, typename T3>
1185 class iuPairwiseGenerator3 : public iuPairwiseGeneratorBase
1186 {
1187  typedef iuParamGenerator<T1> Generator1;
1188  typedef iuParamGenerator<T2> Generator2;
1189  typedef iuParamGenerator<T3> Generator3;
1190 
1191  static const int kRAW_COUNT = 3;
1192  typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;
1193  typedef ::std::vector< _MyParamIndexes > ParamIndexesList;
1194 
1195 public:
1196  typedef tuples::tuple<T1, T2, T3> ParamType;
1197 public:
1198  static iuIParamGenerator< ParamType >* Create(Generator1 g1, Generator2 g2, Generator3 g3)
1199  {
1200  ParamIndexesList list;
1201  ::std::vector<T1> params1;
1202  ::std::vector<T2> params2;
1203  ::std::vector<T3> params3;
1204 
1205  MakeParamVector(params1, g1);
1206  MakeParamVector(params2, g2);
1207  MakeParamVector(params3, g3);
1208 
1209  int count_list[] = {
1210  static_cast<int>(params1.size())
1211  , static_cast<int>(params2.size())
1212  , static_cast<int>(params3.size())
1213  };
1214  MakeIndexList(list, count_list);
1215 
1216  ::std::vector<ParamType> params;
1217 
1218  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
1219  {
1220  const _MyParamIndexes& indexes = *it;
1221  params.push_back( ParamType(
1222  GetParam(params1, indexes, 0)
1223  , GetParam(params2, indexes, 1)
1224  , GetParam(params3, indexes, 2)
1225  ) );
1226  }
1227 
1228  return new iuValuesInParamsGenerator< ParamType >(params);
1229  }
1230 };
1231 */
1232 
1237 #define IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_(i, p1, p2) \
1238  p1<IUTEST_PP_CAT(T, i)> IUTEST_PP_CAT(p2, i);
1239 #define IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_(i, p1, p2) \
1240  MakeParamVector( IUTEST_PP_CAT(p1, i), IUTEST_PP_CAT(p2, i) );
1241 #define IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_(i, param) \
1242  static_cast<int>( IUTEST_PP_CAT(param, i).size() )
1243 #define IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_(i, param) \
1244  GetParam( IUTEST_PP_CAT(param, i), indexes, i)
1245 
1246 #define IIUT_DECL_PAIRWISE_GENERATOR_(n) \
1247  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
1248  class IUTEST_PP_CAT(iuPairwiseGenerator, n) IUTEST_CXX_FINAL : public iuPairwiseGeneratorBase { \
1249  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, typedef iuParamGenerator, Generator) \
1250  typedef ParamIndexes<n> _MyParamIndexes; \
1251  typedef ::std::vector< _MyParamIndexes > ParamIndexesList; \
1252  public: typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType; \
1253  static iuIParamGenerator< ParamType >* Create( \
1254  IUTEST_PP_ENUM_BINARY_PARAMS(n, Generator, g) ) { \
1255  ParamIndexesList list; \
1256  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, ::std::vector, params) \
1257  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_, params, g) \
1258  int count_list[] = { IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_, params) }; \
1259  MakeIndexList(list, count_list); \
1260  ::std::vector<ParamType> params; \
1261  for( typename ParamIndexesList::const_iterator it=list.begin(), end=list.end(); it != end; ++it ) { \
1262  const _MyParamIndexes& indexes = *it; \
1263  params.push_back( ParamType( IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_, params) ) ); \
1264  } \
1265  return new iuValuesInParamsGenerator< ParamType >(params); \
1266  } \
1267  }
1268 
1273 IIUT_DECL_PAIRWISE_GENERATOR_(3);
1274 IIUT_DECL_PAIRWISE_GENERATOR_(4);
1275 IIUT_DECL_PAIRWISE_GENERATOR_(5);
1276 IIUT_DECL_PAIRWISE_GENERATOR_(6);
1277 IIUT_DECL_PAIRWISE_GENERATOR_(7);
1278 IIUT_DECL_PAIRWISE_GENERATOR_(8);
1279 IIUT_DECL_PAIRWISE_GENERATOR_(9);
1280 
1281 #undef IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_
1282 #undef IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_
1283 #undef IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_
1284 #undef IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_
1285 #undef IIUT_DECL_PAIRWISE_GENERATOR_
1286 
1287 /*
1288 template<typename Generator1, typename Generator2>
1289 class iuPairwiseHolder2
1290 {
1291  typedef iuPairwiseHolder2<Generator1, Generator2> _Myt;
1292 public:
1293  iuPairwiseHolder2(const Generator1& g1, const Generator2& g2)
1294  : m_g1(g1), m_g2(g2) {}
1295 
1296 public:
1297  template<typename T1, typename T2>
1298  operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
1299  {
1300  return iuPairwiseGenerator2<T1, T2>::Create(
1301  static_cast< iuIParamGenerator<T1>* >(m_g1)
1302  , static_cast< iuIParamGenerator<T2>* >(m_g2)
1303  );
1304  }
1305 
1306 public:
1307  template<typename Other>
1308  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1309  {
1310  return iuConcatParamHolder<_Myt, Other>(*this, g);
1311  }
1312 
1313 private:
1314  _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION;
1315 private:
1316  const Generator1 m_g1;
1317  const Generator2 m_g2;
1318 };
1319 */
1320 
1321 #define IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_(i, p1, p2) IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
1322 #define IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_(i, p1, p2) \
1323  static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
1324 #define IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_(i, p1, p2) IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
1325 #if IUTEST_HAS_CONCAT
1326 # define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_() \
1327  template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
1328  return iuConcatParamHolder<_Myt, Other>(*this, g); }
1329 #else
1330 # define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_()
1331 #endif
1332 
1333 #define IIUT_DECL_PAIRWISE_HOLDER_(n) \
1334  template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) > \
1335  class IUTEST_PP_CAT(iuPairwiseHolder, n) { \
1336  typedef IUTEST_PP_CAT(iuPairwiseHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt; \
1337  public: IUTEST_PP_CAT(iuPairwiseHolder, n)( \
1338  IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
1339  : IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_, m_g, g) {} \
1340  template< IUTEST_PP_ENUM_PARAMS(n, typename T) > \
1341  operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* () const { \
1342  return IUTEST_PP_CAT(iuPairwiseGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >::Create( \
1343  IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_, T, m_g) ); \
1344  } \
1345  IIUT_DECL_PAIRWISE_HOLDER_CONCAT_() \
1346  private: _Myt& operator = (const _Myt&) IUTEST_CXX_DELETED_FUNCTION; \
1347  IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_, const Generator, m_g) \
1348  }
1349 
1350 IIUT_DECL_PAIRWISE_HOLDER_(2);
1351 IIUT_DECL_PAIRWISE_HOLDER_(3);
1352 IIUT_DECL_PAIRWISE_HOLDER_(4);
1353 IIUT_DECL_PAIRWISE_HOLDER_(5);
1354 IIUT_DECL_PAIRWISE_HOLDER_(6);
1355 IIUT_DECL_PAIRWISE_HOLDER_(7);
1356 IIUT_DECL_PAIRWISE_HOLDER_(8);
1357 IIUT_DECL_PAIRWISE_HOLDER_(9);
1358 
1359 #undef IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_
1360 #undef IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_
1361 #undef IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_
1362 #undef IIUT_DECL_PAIRWISE_HOLDER_CONCAT_
1363 #undef IIUT_DECL_PAIRWISE_HOLDER_
1364 
1365 #endif
1366 
1367 #endif
1368 
1369 #if IUTEST_HAS_VALUESGEN
1370 
1375 template<typename StdGenerator>
1376 class iuValuesParamsGeneratorHolder
1377 {
1378  typedef iuValuesParamsGeneratorHolder<StdGenerator> _Myt;
1379 public:
1380  iuValuesParamsGeneratorHolder(size_t num, const StdGenerator& g)
1381  : m_num(num), m_g(g)
1382  {}
1383 public:
1384  template<typename T>
1385  operator iuIParamGenerator<T>* () const
1386  {
1387  ::std::vector<T> params(m_num);
1388  ::std::generate(params.begin(), params.end(), m_g);
1389  return new iuValuesInParamsGenerator<T>( params );
1390  }
1391 
1392 public:
1393 #if IUTEST_HAS_CONCAT
1394  template<typename Other>
1395  iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
1396  {
1397  return iuConcatParamHolder<_Myt, Other>(*this, g);
1398  }
1399 #endif
1400 
1401 private:
1402  size_t m_num;
1403  StdGenerator m_g;
1404 };
1405 
1409 template<typename T, typename F>
1410 class iuRandomFilterParamGenerator
1411 {
1412  typedef T type;
1413 public:
1414  iuRandomFilterParamGenerator(const F& fn, unsigned int seed)
1415  : m_fn(fn), m_rnd(seed) {}
1416 
1417  type operator ()()
1418  {
1419  type val = m_rnd.genrand();
1420  for( ; !(m_fn)(val); val = m_rnd.genrand() ) {}
1421  return val;
1422  }
1423 private:
1424  F m_fn;
1425  iuTypedRandom<type> m_rnd;
1426 };
1427 
1428 #endif
1429 
1430 #if IUTEST_HAS_RANDOMVALUES
1431 
1435 class iuRandomParamsHolder
1436 {
1437 public:
1438  explicit iuRandomParamsHolder(size_t num, unsigned int seed=0) IUTEST_CXX_NOEXCEPT_SPEC
1439  : m_num(num), m_seed(seed) {}
1440 public:
1441  template<typename T>
1442  operator iuIParamGenerator<T>* () const
1443  {
1444  unsigned int seed = m_seed;
1445  if( seed == 0 )
1446  {
1447  seed = GetIndefiniteValue();
1448  }
1449  iuValuesParamsGeneratorHolder< iuTypedRandom<T> > gen( m_num, iuTypedRandom<T>(seed) );
1450  return gen;
1451  }
1452 
1453 public:
1454 #if IUTEST_HAS_CONCAT
1455  template<typename Other>
1456  iuConcatParamHolder<iuRandomParamsHolder, Other> operator + (const Other& g) const
1457  {
1458  return iuConcatParamHolder<iuRandomParamsHolder, Other>(*this, g);
1459  }
1460 #endif
1461 
1462 private:
1463  size_t m_num;
1464  unsigned int m_seed;
1465 };
1466 
1467 #endif
1468 
1469 } // end of namespace detail
1470 } // end of namespace iutest
1471 
1472 #endif
1473 
1474 #endif // INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_
static detail::iuRandom & genrand()
乱数生成器
Definition: iutest_env.hpp:354
static unsigned int get_random_seed()
乱数シード
Definition: iutest_env.hpp:355
#define IUTEST_CXX_DELETED_FUNCTION
delete function
Definition: iutest_compiler.hpp:445
#define IUTEST_CXX_FINAL
final definition
Definition: iutest_compiler.hpp:756
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:747
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:811
iutest root namespace
Definition: iutest_charcode.hpp:33
detail::type_fit_t< 4 >::UInt UInt32
32 bit 符号なし整数型
Definition: iutest_defs.hpp:503