Classdesc  3.D29
random_init_base.h
1 /*
2  @copyright Russell Standish 2000-2014
3  @author Russell Standish
4  This file is part of Classdesc
5 
6  Open source licensed under the MIT license. See LICENSE for details.
7 */
8 
9 #ifndef RANDOM_INIT_BASE_H
10 #define RANDOM_INIT_BASE_H
11 #include "classdesc.h"
12 #include <sstream>
13 #include <limits>
14 #include <cstdlib>
15 #include <cstdarg>
16 
17 namespace classdesc
18 {
19 
21  {
22  public:
24  virtual double rand() {return double(std::rand())/RAND_MAX;}
25  virtual ~random_init_t() {}
26  };
27 
28  template <class T> void random_init(random_init_t&, const string&, T&);
29  // constant objects cannot be initialised
30  template <class T> void random_initp(random_init_t&, const string&, const T&)
31  {}
32 
35  template <class T> void random_init_normalise(T&);
36 
37  // basic types
38  template <class T> typename
39  enable_if<And<is_arithmetic<T>,Not<is_floating_point<T> > >, void>::T
40  random_initp(random_init_t& r, const string&, T& a, dummy<0> dum=0)
41  {
42  a=T(std::numeric_limits<T>::max()*r.rand());
43  }
44 
45  // floating point types need to be truncated to account for rounding
46  // in ASCII serialisations
47  template <class T> typename
48  enable_if<is_floating_point<T>, void>::T
49  random_initp(random_init_t& r, const string&, T& a, dummy<0> dum=0)
50  {
51  std::ostringstream o;
52  o<<T(std::numeric_limits<T>::max()*r.rand());
53  std::istringstream is(o.str());
54  is>>a;
55  }
56 
57  template <> inline
58  void random_init(random_init_t& r, const string&, bool& a)
59  {
60  a=r.rand()>=0.5;
61  }
62 
63  // strings
64  template <class T>
65  void random_init(random_init_t& r, const string& d, std::basic_string<T>& a)
66  {
67  // randomly fill up to 10 elements
68  a.resize(10*r.rand());
69  for (size_t i=0; i<a.size(); ++i)
70  random_init(r,d,a[i]);
71  }
72 
73  // array handling
74  template <class T>
75  void random_init(random_init_t& r, const string& d, is_array ia, const T& a,
76  int ndims,size_t ncopies,...)
77  {
78  std::va_list ap;
79  va_start(ap,ncopies);
80  size_t cnt=ncopies;
81  for (int i=ndims-2; i>=0; --i) cnt*=va_arg(ap,size_t);
82  va_end(ap);
83  for (size_t i=0; i<cnt; ++i)
84  random_init(r,d,(&a)[i]);
85  }
86 
87 
92  template <class T> void random_init(random_init_t& r, const string& d,
93  Enum_handle<T> arg)
94  {
95  // randomly select from the range of valid enum values.
96  int idx=int(enum_keys<T>().size()*r.rand());
97  arg=enum_keysData<T>().keysData[idx].value;
98  }
99 
100 
102  template <class T> typename
103  enable_if<is_sequence<T>, void>::T
104  random_initp(random_init_t& r, const string& d, T& a, dummy<1> dum=0)
105  {
106  // randomly fill up to 10 elements
107  a.resize(10*r.rand());
108  for (typename T::iterator i=a.begin(); i!=a.end(); ++i)
109  random_init(r,d,*i);
110  }
111 
112  template <class T1, class T2>
113  void random_init(random_init_t& r, const string& d, std::pair<T1,T2>& a)
114  {
115  random_init(r,d+".first",a.first);
116  random_init(r,d+".second",a.second);
117  }
118 
119  template <class T> typename
120  enable_if<is_associative_container<T>, void>::T
121  random_initp(random_init_t& r, const string& d, T& a, dummy<1> dum=0)
122  {
123  int numElem=int(10*r.rand());
124  for (int i=0; i<numElem; ++i)
125  {
126  typename T::value_type v;
127  random_init(r,d,v);
128  a.insert(v);
129  }
130  }
131 
132  // regular pointers
133  template <class T> void random_initp(random_init_t&, const string&, T*) {}
134 
135  /*
136  Method pointers
137  */
138  template <class C, class T>
139  void random_init(random_init_t&, const string&, C&, T) {}
140 
141  /*
142  const static support
143  */
144  template <class T>
145  void random_init(random_init_t&, const string&, is_const_static, T) {}
146 
147  // static methods
148  template <class T, class U>
149  void random_init(random_init_t&, const string&, is_const_static, const T&, U) {}
150 
151  // Exclude
152  template <class T>
153  void random_init(random_init_t& targ, const string& desc, Exclude<T>& arg) {}
154 
155  template <class T>
156  void random_init_onbase(random_init_t& targ, const string& desc, T& arg)
157  {random_init(targ,desc,arg);}
158 
159 
160 }
161 
162 namespace classdesc_access
163 {
164  template <class T> struct access_random_init;
165 }
166 
167 using classdesc::random_init;
168 using classdesc::random_init_onbase;
169 
170 #endif
Definition: random_init_base.h:20
virtual double rand()
return a uniform random number in [0..1)
Definition: random_init_base.h:24
Definition: classdesc.h:572
std::string idx(const std::string &prefix, size_t i)
utility for generating index keys (for use with arrays)
Definition: xml_common.h:14
Definition: classdesc.h:291
void random_init_normalise(T &)
Definition: random_init_epilogue.h:123