1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 /**
8    Utility classes for testing.
9    (FIXME: move to some publicly-available place?)
10 */
11 
12 #ifndef ALPS_UTILITIES_TEST_TEST_UTILS_HPP_bc68762a102b40968489f16ee603e253
13 #define ALPS_UTILITIES_TEST_TEST_UTILS_HPP_bc68762a102b40968489f16ee603e253
14 
15 #include <complex>
16 #include <iostream>
17 #include <cmath> // for pow()
18 #include <boost/foreach.hpp>
19 
20 
21 namespace alps {
22     namespace testing {
23         // Debug printing of a vector
24         template <typename T>
operator <<(std::ostream & strm,const std::vector<T> & vec)25         std::ostream& operator<<(std::ostream& strm, const std::vector<T>& vec)
26         {
27             typedef std::vector<T> vtype;
28             typedef typename vtype::const_iterator itype;
29 
30             strm << "[";
31             itype it=vec.begin();
32             const itype end=vec.end();
33 
34             if (end!=it) {
35                 strm << *it;
36                 for (++it; end!=it; ++it) {
37                     strm << ", " << *it;
38                 }
39             }
40             strm << "]";
41 
42             return strm;
43         }
44 
45 
46         // Data generators: T=int, char, double
47         template <typename T>
48         class datapoint {
49           public:
50             /// Returns different values of type T for the different value of the argument.
get(bool choice)51             static T get(bool choice)
52             {
53                 return T(choice?('A'+.25):('B'+.75)); // good for T=int,char,double
54             }
55 
56             /// Returns different values of type T for the different value of the argument.
get(unsigned int choice)57             static T get(unsigned int choice)
58             {
59                 if (choice==0) return 0;
60                 return T(choice+std::pow(2.0,-double(choice))); // good for T=int,char,double
61             }
62 
63             /// Returns different values of type T for the different value of the argument.
get(int choice)64             static T get(int choice) { return get((unsigned int)choice); }
65 
66             /// Returns different values of type T for the different value of the argument.
67             /** Defined for interface uniformity with the vector variant */
68             template <typename D>
get(D choice,std::size_t)69             static T get(D choice, std::size_t)
70             {
71                 return get(choice);
72             }
73         };
74 
75 
76         template <>
77         class datapoint<bool> {
78           public:
79             /// Returns different bool values for the different value of the argument.
get(bool choice)80             static bool get(bool choice) { return choice; }
81 
82             /// Returns different bool values for the different value of the argument.
get(unsigned int choice)83             static bool get(unsigned int choice)
84             {
85                 return (choice%2==1);
86             }
87 
88             /// Returns different bool values for the different value of the argument.
get(int choice)89             static bool get(int choice) { return get((unsigned int)choice); }
90 
91             /// Returns different bool values for the different value of the argument.
92             template <typename D>
get(D choice,std::size_t)93             static bool get(D choice, std::size_t) { return get(choice); }
94         };
95 
96         template <>
97         class datapoint<std::string> {
98           public:
99             /// Returns different string values for the different value of the argument.
get(unsigned int choice)100             static std::string get(unsigned int choice)
101             {
102                 const char zero='!';
103                 std::string out;
104                 if (choice==0) {
105                     out=std::string(1,zero);
106                 } else {
107                     const int radix=(127-zero);
108                     while (choice>0) {
109                         out.insert((std::size_t) 0,(std::size_t) 1,zero+char(choice%radix));
110                         choice/=radix;
111                     }
112                 }
113                 return out;
114             }
115 
116             /// Returns different string values (of size sz) for the different value of the argument.
get(unsigned int choice,std::size_t sz)117             static std::string get(unsigned int choice, std::size_t sz) {
118                 std::string out=get(choice);
119                 const std::size_t base_sz=out.size();
120                 if (sz<base_sz) {
121                     throw std::invalid_argument("get<std::string>(): the requested size"
122                                                 " is too short for the string to be unique");
123                 }
124                 const std::size_t pad_sz=sz-base_sz;
125                 out.insert(0,pad_sz,'!');
126                 return out;
127             }
128 
129             /// Returns different string values (of size sz) for the different value of the argument.
get(int choice,std::size_t sz)130             static std::string get(int choice, std::size_t sz) { return get((unsigned int)choice, sz); }
131 
132             /// Returns different values of type T for the different value of the argument.
get(int choice)133             static std::string get(int choice) { return get((unsigned int)choice); }
134 
135             /// Returns different string values for the different value of the argument.
get(bool choice)136             static std::string get(bool choice) { return choice?"one":"another"; }
137 
138             /// Returns different string values (of size sz) for the different value of the argument.
get(bool choice,std::size_t sz)139             static std::string get(bool choice, std::size_t sz) {
140                 const std::string base=get(choice);
141                 const std::size_t base_sz=base.size();
142                 std::size_t nrep=(sz+base_sz-1)/base_sz;
143                 std::string ret;
144                 while (nrep--) ret.append(base);
145                 ret.resize(sz);
146                 return ret;
147             }
148         };
149 
150         template <typename T>
151         class datapoint< std::complex<T> > {
152           public:
153             /// Returns different complex values for the different value of the argument.
get(bool choice)154             static std::complex<T> get(bool choice) {
155                 return std::complex<T>(datapoint<T>::get(choice), datapoint<T>::get(!choice));
156             }
157 
158             /// Returns different values of type T for the different value of the argument.
get(unsigned int choice)159             static std::complex<T> get(unsigned int choice)
160             {
161                 return std::complex<T>(datapoint<T>::get(choice), datapoint<T>::get(choice+1));
162             }
163 
164             /// Returns different values of type T for the different value of the argument.
get(int choice)165             static std::complex<T> get(int choice) { return get((unsigned int)choice); }
166 
167             /// Returns different complex values for the different value of the argument.
168             template <typename D>
get(D choice,std::size_t)169             static std::complex<T> get(D choice, std::size_t) {
170                 return get(choice);
171             }
172         };
173 
174         template <typename T>
175         class datapoint< std::vector<T> > {
176             public:
177             /// Returns different vector values of the specified length for the different value of the argument.
get(bool choice,std::size_t sz)178             static std::vector<T> get(bool choice, std::size_t sz) {
179                 std::vector<T> arr(sz);
180                 BOOST_FOREACH(typename std::vector<T>::reference vref, arr) {
181                     vref=datapoint<T>::get(choice,sz);
182                     choice=!choice;
183                 }
184                 return arr;
185             }
186 
187             /// Returns different vector values of the specified length for the different value of the argument.
get(unsigned int choice,std::size_t sz)188             static std::vector<T> get(unsigned int choice, std::size_t sz)
189             {
190                 std::vector<T> arr(sz);
191                 unsigned int i=0;
192                 BOOST_FOREACH(typename std::vector<T>::reference vref, arr) {
193                     vref=datapoint<T>::get(choice+i,sz);
194                     ++i;
195                 }
196                 return arr;
197             }
198 
199             /// Returns different values of type T for the different value of the argument.
get(int choice,std::size_t sz)200             static std::vector<T> get(int choice, std::size_t sz) { return get((unsigned int)choice, sz); }
201 
202             /// Returns different vector values (length, content) for the different value of the argument.
get(bool choice)203             static std::vector<T> get(bool choice) {
204                 return get(choice, choice?3:4);
205             }
206 
207             /// Returns different vector values (length, content) for the different value of the argument.
get(unsigned int choice)208             static std::vector<T> get(unsigned int choice) {
209                 return get(choice, 5+choice%10);
210             }
211 
212             /// Returns different vector values (length, content) for the different value of the argument.
get(int choice)213             static std::vector<T> get(int choice) { return get((unsigned int)choice); }
214         };
215 
216 
217     } // testing::
218 } // alps::
219 
220 #endif /* ALPS_UTILITIES_TEST_TEST_UTILS_HPP_bc68762a102b40968489f16ee603e253 */
221