| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 1 | // Copyright 2020 The Pigweed Authors | 
|  | 2 | // | 
|  | 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not | 
|  | 4 | // use this file except in compliance with the License. You may obtain a copy of | 
|  | 5 | // the License at | 
|  | 6 | // | 
|  | 7 | //     https://www.apache.org/licenses/LICENSE-2.0 | 
|  | 8 | // | 
|  | 9 | // Unless required by applicable law or agreed to in writing, software | 
|  | 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | 
|  | 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | 
|  | 12 | // License for the specific language governing permissions and limitations under | 
|  | 13 | // the License. | 
|  | 14 |  | 
|  | 15 | #include <array> | 
|  | 16 |  | 
|  | 17 | #include "gtest/gtest.h" | 
| Wyatt Hepler | 6c331ae | 2020-08-04 10:05:11 -0700 | [diff] [blame] | 18 | #include "pw_polyfill/language_feature_macros.h" | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 19 | #include "pw_polyfill/standard.h" | 
| Wyatt Hepler | ecf1923 | 2020-09-02 14:35:09 -0700 | [diff] [blame] | 20 | #include "pw_polyfill/standard_library/bit.h" | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 21 | #include "pw_polyfill/standard_library/cstddef.h" | 
|  | 22 | #include "pw_polyfill/standard_library/iterator.h" | 
|  | 23 | #include "pw_polyfill/standard_library/type_traits.h" | 
| Wyatt Hepler | 8e59f4d | 2020-08-27 10:34:21 -0700 | [diff] [blame] | 24 | #include "pw_polyfill/standard_library/utility.h" | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 25 |  | 
|  | 26 | namespace pw { | 
|  | 27 | namespace polyfill { | 
|  | 28 | namespace { | 
|  | 29 |  | 
|  | 30 | PW_INLINE_VARIABLE constexpr int foo = 42; | 
|  | 31 |  | 
|  | 32 | static_assert(foo == 42, "Error!"); | 
|  | 33 |  | 
|  | 34 | static_assert(PW_CXX_STANDARD_IS_SUPPORTED(98), "C++98 must be supported"); | 
|  | 35 | static_assert(PW_CXX_STANDARD_IS_SUPPORTED(11), "C++11 must be supported"); | 
|  | 36 |  | 
|  | 37 | #if __cplusplus >= 201402L | 
|  | 38 | static_assert(PW_CXX_STANDARD_IS_SUPPORTED(14), "C++14 must be not supported"); | 
|  | 39 | #else | 
|  | 40 | static_assert(!PW_CXX_STANDARD_IS_SUPPORTED(14), "C++14 must be supported"); | 
|  | 41 | #endif  // __cplusplus >= 201402L | 
|  | 42 |  | 
|  | 43 | #if __cplusplus >= 201703L | 
|  | 44 | static_assert(PW_CXX_STANDARD_IS_SUPPORTED(17), "C++17 must be not supported"); | 
|  | 45 | #else | 
|  | 46 | static_assert(!PW_CXX_STANDARD_IS_SUPPORTED(17), "C++17 must be supported"); | 
|  | 47 | #endif  // __cplusplus >= 201703L | 
|  | 48 |  | 
| Wyatt Hepler | 8e59f4d | 2020-08-27 10:34:21 -0700 | [diff] [blame] | 49 | TEST(Array, ToArray_StringLiteral) { | 
|  | 50 | std::array<char, sizeof("literally!")> array = std::to_array("literally!"); | 
|  | 51 | EXPECT_TRUE(std::strcmp(array.data(), "literally!") == 0); | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | TEST(Array, ToArray_Inline) { | 
|  | 55 | constexpr std::array<int, 3> kArray = std::to_array({1, 2, 3}); | 
|  | 56 | static_assert(kArray.size() == 3); | 
|  | 57 | EXPECT_TRUE(kArray[0] == 1); | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 | TEST(Array, ToArray_Array) { | 
|  | 61 | char c_array[] = "array!"; | 
|  | 62 | std::array<char, sizeof("array!")> array = std::to_array(c_array); | 
|  | 63 | EXPECT_TRUE(std::strcmp(array.data(), "array!") == 0); | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | struct MoveOnly { | 
|  | 67 | MoveOnly(char ch) : value(ch) {} | 
|  | 68 |  | 
|  | 69 | MoveOnly(const MoveOnly&) = delete; | 
|  | 70 | MoveOnly& operator=(const MoveOnly&) = delete; | 
|  | 71 |  | 
|  | 72 | MoveOnly(MoveOnly&&) = default; | 
|  | 73 | MoveOnly& operator=(MoveOnly&&) = default; | 
|  | 74 |  | 
|  | 75 | char value; | 
|  | 76 | }; | 
|  | 77 |  | 
|  | 78 | TEST(Array, ToArray_MoveOnly) { | 
|  | 79 | MoveOnly c_array[]{MoveOnly('a'), MoveOnly('b')}; | 
|  | 80 | std::array<MoveOnly, 2> array = std::to_array(std::move(c_array)); | 
|  | 81 | EXPECT_TRUE(array[0].value == 'a'); | 
|  | 82 | EXPECT_TRUE(array[1].value == 'b'); | 
|  | 83 | } | 
|  | 84 |  | 
| Wyatt Hepler | ecf1923 | 2020-09-02 14:35:09 -0700 | [diff] [blame] | 85 | TEST(Bit, Endian) { | 
|  | 86 | if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) { | 
|  | 87 | EXPECT_TRUE(std::endian::native == std::endian::big); | 
|  | 88 | } else if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) { | 
|  | 89 | EXPECT_TRUE(std::endian::native == std::endian::little); | 
|  | 90 | } else { | 
|  | 91 | FAIL(); | 
|  | 92 | } | 
|  | 93 | } | 
|  | 94 |  | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 95 | TEST(Cstddef, Byte_Operators) { | 
|  | 96 | std::byte value = std::byte(0); | 
|  | 97 | EXPECT_TRUE((value | std::byte(0x12)) == std::byte(0x12)); | 
|  | 98 | EXPECT_TRUE((value & std::byte(0x12)) == std::byte(0)); | 
|  | 99 | EXPECT_TRUE((value ^ std::byte(0x12)) == std::byte(0x12)); | 
|  | 100 | EXPECT_TRUE(~std::byte(0) == std::byte(-1)); | 
|  | 101 | EXPECT_TRUE((std::byte(1) << 3) == std::byte(0x8)); | 
|  | 102 | EXPECT_TRUE((std::byte(0x8) >> 3) == std::byte(1)); | 
|  | 103 | } | 
|  | 104 |  | 
|  | 105 | TEST(Cstddef, Byte_AssignmentOperators) { | 
|  | 106 | std::byte value = std::byte(0); | 
|  | 107 | EXPECT_TRUE((value |= std::byte(0x12)) == std::byte(0x12)); | 
|  | 108 | EXPECT_TRUE((value &= std::byte(0x0F)) == std::byte(0x02)); | 
|  | 109 | EXPECT_TRUE((value ^= std::byte(0xFF)) == std::byte(0xFD)); | 
|  | 110 | EXPECT_TRUE((value <<= 4) == std::byte(0xD0)); | 
|  | 111 | EXPECT_TRUE((value >>= 5) == std::byte(0x6)); | 
|  | 112 | } | 
|  | 113 |  | 
| Wyatt Hepler | 6c331ae | 2020-08-04 10:05:11 -0700 | [diff] [blame] | 114 | // Check that consteval is at least equivalent to constexpr. | 
|  | 115 | consteval int ConstevalFunction() { return 123; } | 
|  | 116 | static_assert(ConstevalFunction() == 123); | 
|  | 117 |  | 
|  | 118 | int c_array[5423] = {}; | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 119 | std::array<int, 32> array; | 
|  | 120 |  | 
|  | 121 | TEST(Iterator, Size) { | 
|  | 122 | EXPECT_TRUE(std::size(c_array) == sizeof(c_array) / sizeof(*c_array)); | 
|  | 123 | EXPECT_TRUE(std::size(array) == array.size()); | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | TEST(Iterator, Data) { | 
|  | 127 | EXPECT_TRUE(std::data(c_array) == c_array); | 
|  | 128 | EXPECT_TRUE(std::data(array) == array.data()); | 
|  | 129 | } | 
|  | 130 |  | 
| Wyatt Hepler | 6c331ae | 2020-08-04 10:05:11 -0700 | [diff] [blame] | 131 | constinit bool mutable_value = true; | 
|  | 132 |  | 
|  | 133 | TEST(Constinit, ValueIsMutable) { | 
|  | 134 | ASSERT_TRUE(mutable_value); | 
|  | 135 | mutable_value = false; | 
|  | 136 | ASSERT_FALSE(mutable_value); | 
|  | 137 | mutable_value = true; | 
|  | 138 | } | 
|  | 139 |  | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 140 | TEST(TypeTraits, Aliases) { | 
|  | 141 | static_assert( | 
|  | 142 | std::is_same<std::aligned_storage_t<40, 40>, | 
|  | 143 | typename std::aligned_storage<40, 40>::type>::value, | 
|  | 144 | "Alias must be defined"); | 
|  | 145 |  | 
|  | 146 | static_assert(std::is_same<std::common_type_t<int, bool>, | 
|  | 147 | typename std::common_type<int, bool>::type>::value, | 
|  | 148 | "Alias must be defined"); | 
|  | 149 |  | 
|  | 150 | static_assert( | 
|  | 151 | std::is_same<std::conditional_t<false, int, char>, | 
|  | 152 | typename std::conditional<false, int, char>::type>::value, | 
|  | 153 | "Alias must be defined"); | 
|  | 154 |  | 
|  | 155 | static_assert( | 
|  | 156 | std::is_same<std::decay_t<int>, typename std::decay<int>::type>::value, | 
|  | 157 | "Alias must be defined"); | 
|  | 158 |  | 
|  | 159 | static_assert(std::is_same<std::enable_if_t<true, int>, | 
|  | 160 | typename std::enable_if<true, int>::type>::value, | 
|  | 161 | "Alias must be defined"); | 
|  | 162 |  | 
|  | 163 | static_assert(std::is_same<std::make_signed_t<int>, | 
|  | 164 | typename std::make_signed<int>::type>::value, | 
|  | 165 | "Alias must be defined"); | 
|  | 166 |  | 
|  | 167 | static_assert(std::is_same<std::make_unsigned_t<int>, | 
|  | 168 | typename std::make_unsigned<int>::type>::value, | 
|  | 169 | "Alias must be defined"); | 
|  | 170 |  | 
|  | 171 | static_assert(std::is_same<std::remove_cv_t<int>, | 
|  | 172 | typename std::remove_cv<int>::type>::value, | 
|  | 173 | "Alias must be defined"); | 
|  | 174 |  | 
|  | 175 | static_assert(std::is_same<std::remove_pointer_t<int>, | 
|  | 176 | typename std::remove_pointer<int>::type>::value, | 
|  | 177 | "Alias must be defined"); | 
|  | 178 |  | 
|  | 179 | static_assert(std::is_same<std::remove_reference_t<int>, | 
|  | 180 | typename std::remove_reference<int>::type>::value, | 
|  | 181 | "Alias must be defined"); | 
|  | 182 | } | 
|  | 183 |  | 
| Wyatt Hepler | 8e59f4d | 2020-08-27 10:34:21 -0700 | [diff] [blame] | 184 | TEST(Utility, IntegerSequence) { | 
|  | 185 | static_assert(std::integer_sequence<int>::size() == 0); | 
|  | 186 | static_assert(std::integer_sequence<int, 9, 8, 7>::size() == 3); | 
|  | 187 | static_assert(std::make_index_sequence<1>::size() == 1); | 
|  | 188 | static_assert(std::make_index_sequence<123>::size() == 123); | 
|  | 189 | } | 
|  | 190 |  | 
| Wyatt Hepler | c542a5d | 2020-01-15 15:43:10 -0800 | [diff] [blame] | 191 | }  // namespace | 
|  | 192 | }  // namespace polyfill | 
|  | 193 | }  // namespace pw |