MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
byteorder-t.cc
1 /* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include "my_config.h"
17 #include <gtest/gtest.h>
18 #include <limits>
19 
20 #include "my_global.h"
21 
22 namespace byteorder_unittest {
23 
24 using std::numeric_limits;
25 
26 #if defined(GTEST_HAS_PARAM_TEST)
27 
28 /*
29  This class is used to instantiate parameterized tests for float and double.
30  */
31 template<typename T>
32 class FloatingTest
33 {
34 protected:
35  T input;
36  T output;
37  uchar buf[sizeof(T)];
38 };
39 
40 class Float4Test : public FloatingTest<float>,
41  public ::testing::TestWithParam<float>
42 {
43  virtual void SetUp()
44  {
45  input= GetParam();
46  output= numeric_limits<float>::quiet_NaN();
47  }
48 };
49 
50 INSTANTIATE_TEST_CASE_P(Foo, Float4Test,
51  ::testing::Values(numeric_limits<float>::min(),
52  numeric_limits<float>::max(),
53  numeric_limits<float>::epsilon(),
54  -numeric_limits<float>::min(),
55  -numeric_limits<float>::max(),
56  -numeric_limits<float>::epsilon(),
57  -1.0f, 0.0f, 1.0f));
58 /*
59  The actual test case for float: store and get some values.
60  */
61 TEST_P(Float4Test, PutAndGet)
62 {
63  float4store(buf, input);
64  float4get(output, buf);
65  EXPECT_EQ(input, output);
66  floatstore(buf, input);
67  floatget(output, buf);
68  EXPECT_EQ(input, output);
69 }
70 
71 
72 class Float8Test : public FloatingTest<double>,
73  public ::testing::TestWithParam<double>
74 {
75  virtual void SetUp()
76  {
77  input= GetParam();
78  output= numeric_limits<double>::quiet_NaN();
79  }
80 };
81 
82 INSTANTIATE_TEST_CASE_P(Foo, Float8Test,
83  ::testing::Values(numeric_limits<double>::min(),
84  numeric_limits<double>::max(),
85  numeric_limits<double>::epsilon(),
86  -numeric_limits<double>::min(),
87  -numeric_limits<double>::max(),
88  -numeric_limits<double>::epsilon(),
89  -1.0, 0.0, 1.0));
90 /*
91  The actual test case for double: store and get some values.
92  */
93 TEST_P(Float8Test, PutAndGet)
94 {
95  float8store(buf, input);
96  float8get(output, buf);
97  EXPECT_EQ(input, output);
98  doublestore(buf, input);
99  doubleget(output, buf);
100  EXPECT_EQ(input, output);
101 }
102 
103 #endif // GTEST_HAS_PARAM_TEST
104 
105 
106 #if defined(GTEST_HAS_TYPED_TEST)
107 
108 /*
109  A test fixture class, parameterized on type.
110  Will be instantiated for all IntegralTypes below.
111  */
112 template<typename T>
113 class IntegralTest : public ::testing::Test
114 {
115 protected:
116  typedef std::numeric_limits<T> Limit;
117 
118  T input;
119  T output;
120  uchar buf[sizeof(T)];
121 
122  typename std::vector<T> values;
123 
124  IntegralTest() : input(0), output(0) {}
125 
126  virtual void SetUp()
127  {
128  values.push_back(Limit::min());
129  values.push_back(Limit::min() / T(2));
130  values.push_back(T(0));
131  values.push_back(T(42));
132  values.push_back(Limit::max() / T(2));
133  values.push_back(Limit::max());
134  }
135 };
136 
137 /*
138  A class to make our 3, 5 and 6 digit integers look like builtins.
139  */
140 template<int ndigits>
141 struct sizeNint
142 {
143  // For numeric_limits.
144  typedef ulonglong value_type;
145 
146  sizeNint() : value(0) {}
147  explicit sizeNint(ulonglong v)
148  {
149  switch(ndigits)
150  {
151  case 3: value= v & 0xFFFFFFULL; break;
152  case 5: value= v & 0xFFFFFFFFFFULL; break;
153  case 6: value= v & 0xFFFFFFFFFFFFULL; break;
154  default: ADD_FAILURE() << "unxpected number of digits";
155  }
156  }
157 
158  sizeNint operator/(const sizeNint &that) const
159  { return sizeNint(this->value / that.value); }
160 
161  bool operator==(const sizeNint &that) const
162  { return this->value == that.value; }
163 
164  ulonglong value;
165 };
166 
167 // googletest needs to be able to print arguments to EXPECT_EQ.
168 template<int ndigits>
169 std::ostream &operator<<(std::ostream &s, const sizeNint<ndigits> &v)
170 { return s << v.value; }
171 
172 // Instantiate the PutAndGet test for all these types:
173 typedef ::testing::Types<short, ushort,
174  sizeNint<3>, sizeNint<5>, sizeNint<6>,
175  int, unsigned,
176  longlong, ulonglong> IntegralTypes;
177 
178 TYPED_TEST_CASE(IntegralTest, IntegralTypes);
179 
180 /*
181  Wrap all the __get, __store, __korr macros in functions.
182  */
183 template<typename T> void put_integral(uchar *buf, T val)
184 { ADD_FAILURE() << "unknown type in put_integral"; }
185 template<typename T> void get_integral(T &val, uchar *buf)
186 { ADD_FAILURE() << "unknown type in get_integral"; }
187 
188 template<> void put_integral(uchar *buf, short val) { shortstore(buf, val); }
189 template<> void get_integral(short &val, uchar *buf) { shortget(val, buf); }
190 
191 // Hmm, there's no ushortstore...
192 template<> void put_integral(uchar *buf, ushort val) { shortstore(buf, val); }
193 template<> void get_integral(ushort &val, uchar *buf) { ushortget(val, buf); }
194 
195 template<> void put_integral(uchar *buf, int val) { longstore(buf, val); }
196 template<> void get_integral(int &val, uchar *buf) { longget(val, buf); }
197 
198 // Hmm, there's no ulongstore...
199 template<> void put_integral(uchar *buf, unsigned val) { longstore(buf, val); }
200 template<> void get_integral(unsigned &val, uchar *buf) { ulongget(val, buf); }
201 
202 template<> void put_integral(uchar *buf, longlong val)
203 { longlongstore(buf, val); }
204 template<> void get_integral(longlong &val, uchar *buf)
205 { longlongget(val, buf); }
206 
207 // Reading ulonglong is different from all the above ....
208 template<> void put_integral(uchar *buf, ulonglong val)
209 { int8store(buf, val); }
210 template<> void get_integral(ulonglong &val, uchar *buf)
211 { val= uint8korr(buf); }
212 
213 template<> void put_integral(uchar *buf, sizeNint<3> val)
214 { int3store(buf, val.value); }
215 template<> void get_integral(sizeNint<3> &val, uchar *buf)
216 { val.value= uint3korr(buf); }
217 
218 template<> void put_integral(uchar *buf, sizeNint<5> val)
219 { int5store(buf, val.value); }
220 template<> void get_integral(sizeNint<5> &val, uchar *buf)
221 { val.value= uint5korr(buf); }
222 
223 template<> void put_integral(uchar *buf, sizeNint<6> val)
224 { int6store(buf, val.value); }
225 template<> void get_integral(sizeNint<6> &val, uchar *buf)
226 { val.value= uint6korr(buf); }
227 
228 /*
229  This is the actual test which will be instantiated for all IntegralTypes.
230  */
231 TYPED_TEST(IntegralTest, PutAndGet)
232 {
233  for (size_t ix= 0; ix < this->values.size(); ++ix)
234  {
235  this->input= this->values[ix];
236  put_integral(this->buf, this->input);
237  get_integral(this->output, this->buf);
238  // Visual studio rejects: EXPECT_EQ(this->input, this->output);
239  TypeParam myinput= this->input;
240  TypeParam myoutput= this->output;
241  EXPECT_EQ(myinput, myoutput);
242  }
243 }
244 
245 #endif // GTEST_HAS_TYPED_TEST
246 }