Convert some config.h macros to use 0/1
[gromacs.git] / src / gromacs / utility / tests / arrayref.cpp
blobd7868e2d05dbe0ead9b104609d3aeb816344a8fa
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2015,2016, by the GROMACS development team, led by
5 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6 * and including many others, as listed in the AUTHORS file in the
7 * top-level source directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \internal \file
36 * \brief Tests for gmx::ArrayRef and gmx::ConstArrayRef.
38 * \author Mark Abraham <mark.j.abraham@gmail.com>
39 * \ingroup module_utility
41 #include "gmxpre.h"
43 #include "gromacs/utility/arrayref.h"
45 #include "config.h"
47 #include <vector>
49 #include <gtest/gtest.h>
51 #include "gromacs/utility/basedefinitions.h"
52 #include "gromacs/utility/real.h"
54 namespace gmx
57 namespace
60 TEST(EmptyArrayRefTest, IsEmpty)
62 EmptyArrayRef emptyArray = {};
63 ArrayRef<real> empty(emptyArray);
65 EXPECT_EQ(0U, empty.size());
66 EXPECT_TRUE(empty.empty());
69 TEST(EmptyConstArrayRefTest, IsEmpty)
71 EmptyArrayRef emptyArray = {};
72 ConstArrayRef<real> empty(emptyArray);
74 EXPECT_EQ(0U, empty.size());
75 EXPECT_TRUE(empty.empty());
78 #ifdef GTEST_HAS_TYPED_TEST
80 //! Define the types that end up being available as TypeParam in the test cases for both kinds of ArrayRef
81 typedef ::testing::Types<
82 ArrayRef<char>,
83 ArrayRef<unsigned char>,
84 ArrayRef<int>,
85 ArrayRef<unsigned int>,
86 ArrayRef<long>,
87 ArrayRef<unsigned long>,
88 ArrayRef<gmx_int64_t>,
89 ArrayRef<gmx_uint64_t>,
90 ArrayRef<float>,
91 ArrayRef<double>,
92 ConstArrayRef<char>,
93 ConstArrayRef<unsigned char>,
94 ConstArrayRef<int>,
95 ConstArrayRef<unsigned int>,
96 ConstArrayRef<long>,
97 ConstArrayRef<unsigned long>,
98 ConstArrayRef<gmx_int64_t>,
99 ConstArrayRef<gmx_uint64_t>,
100 ConstArrayRef<float>,
101 ConstArrayRef<double>
102 > ArrayRefTypes;
104 /*! \brief Permit all the tests to run on all kinds of ArrayRefs
106 * The main objective is to verify that all the different kinds of
107 * construction lead to the expected result. */
108 template <typename TypeParam>
109 class ArrayRefTest : public ::testing::Test
111 public:
112 typedef TypeParam ArrayRefType;
113 typedef typename ArrayRefType::value_type ValueType;
115 /*! \brief Run the same tests all the time
117 * Note that test cases must call this->runTests(), because
118 * that's how the derived-class templates that implement
119 * type-parameterized tests actually work. */
120 void runTests(ValueType *a,
121 size_t aSize,
122 ValueType *aData,
123 ArrayRefType &arrayRef)
125 ASSERT_EQ(aSize, arrayRef.size());
126 ASSERT_FALSE(arrayRef.empty());
127 EXPECT_EQ(aData, arrayRef.data());
128 EXPECT_EQ(a[0], arrayRef.front());
129 EXPECT_EQ(a[aSize-1], arrayRef.back());
130 for (size_t i = 0; i != aSize; ++i)
132 EXPECT_EQ(a[i], arrayRef[i]);
137 TYPED_TEST_CASE(ArrayRefTest, ArrayRefTypes);
139 /* Welcome back to the past. While you can declare a static array[] of
140 templated type in a class, in C++98, you have to define it outside
141 the class, and when you do, the compiler knows the declaration is
142 incomplete and can't match the types to actual functions. So,
143 declaring locals is the only choice available, so we need macros to
144 avoid duplication. Lovely. */
145 #define DEFINE_ARRAY(a, aSize) \
146 typename TestFixture::ValueType (a)[] = { \
147 static_cast<typename TestFixture::ValueType>(1.2), \
148 static_cast<typename TestFixture::ValueType>(2.4), \
149 static_cast<typename TestFixture::ValueType>(3.1) \
150 }; \
151 size_t (aSize) = sizeof((a)) / sizeof(typename TestFixture::ValueType);
153 TYPED_TEST(ArrayRefTest, MakeWithAssignmentWorks)
155 DEFINE_ARRAY(a, aSize);
156 typename TestFixture::ArrayRefType arrayRef = a;
157 this->runTests(a, aSize, a, arrayRef);
160 TYPED_TEST(ArrayRefTest, ConstructWithTemplateConstructorWorks)
162 DEFINE_ARRAY(a, aSize);
163 typename TestFixture::ArrayRefType arrayRef(a);
164 this->runTests(a, aSize, a, arrayRef);
167 TYPED_TEST(ArrayRefTest, ConstructFromPointersWorks)
169 DEFINE_ARRAY(a, aSize);
170 typename TestFixture::ArrayRefType arrayRef(a, a + aSize);
171 this->runTests(a, aSize, a, arrayRef);
174 TYPED_TEST(ArrayRefTest, MakeFromPointersWorks)
176 DEFINE_ARRAY(a, aSize);
177 typename TestFixture::ArrayRefType arrayRef
178 = TestFixture::ArrayRefType::fromPointers(a, a + aSize);
179 this->runTests(a, aSize, a, arrayRef);
182 TYPED_TEST(ArrayRefTest, MakeFromArrayWorks)
184 DEFINE_ARRAY(a, aSize);
185 typename TestFixture::ArrayRefType arrayRef
186 = TestFixture::ArrayRefType::fromArray(a, aSize);
187 this->runTests(a, aSize, a, arrayRef);
190 TYPED_TEST(ArrayRefTest, ConstructFromVectorWorks)
192 DEFINE_ARRAY(a, aSize);
193 std::vector<typename TestFixture::ValueType> v(a, a + aSize);
194 typename TestFixture::ArrayRefType arrayRef(v);
195 this->runTests(a, v.size(), v.data(), arrayRef);
198 TYPED_TEST(ArrayRefTest, MakeFromVectorWorks)
200 DEFINE_ARRAY(a, aSize);
201 std::vector<typename TestFixture::ValueType> v(a, a + aSize);
202 typename TestFixture::ArrayRefType arrayRef
203 = TestFixture::ArrayRefType::fromVector(v.begin(), v.end());
204 this->runTests(a, v.size(), v.data(), arrayRef);
207 //! Helper struct for the case actually used in mdrun signalling
208 template <typename T>
209 struct Helper
211 public:
212 T a[3];
213 int size;
216 /*! \brief Test of the case actually used in mdrun signalling
218 * There, we take a non-const struct-field array of static length and
219 * make an ArrayRef to it using the template constructor that is
220 * supposed to infer the length from the static size. But on xlc on
221 * BlueGene/Q, if the base type is not char (or unsigned char), the
222 * generated code ends up with an ArrayRef of zero size, so everything
223 * breaks. Presumably the default code path accidentally works for
224 * char.
226 * Fortunately, all current uses of that constructor have a base type
227 * of char, so there's no big problem. Using a pointer-based
228 * constructor does work, if there's ever a problem (and that is
229 * tested above). */
231 TYPED_TEST(ArrayRefTest, ConstructFromStructFieldWithTemplateConstructorWorks)
233 DEFINE_ARRAY(a, aSize);
234 Helper<typename TestFixture::ValueType> h;
235 h.size = aSize;
236 for (int i = 0; i != h.size; ++i)
238 h.a[i] = a[i];
240 typename TestFixture::ArrayRefType arrayRef(h.a);
241 #if GMX_TARGET_BGQ && defined(__xlC__)
242 if (sizeof(typename TestFixture::ValueType) == sizeof(char))
243 #endif
245 this->runTests(h.a, h.size, h.a, arrayRef);
249 #else // GTEST_HAS_TYPED_TEST
251 /* A dummy test that at least signals that something is missing if one runs the
252 * unit test executable itself.
254 TEST(DISABLED_ArrayRefTest, GenericTests)
256 ADD_FAILURE()
257 << "Tests for generic ArrayRef functionality require support for "
258 << "Google Test typed tests, which was not available when the tests "
259 << "were compiled.";
262 #endif // GTEST_HAS_TYPED_TEST
264 } // namespace
266 } // namespace