| // Copyright 2021 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <lib/stdcompat/memory.h> |
| #include <lib/stdcompat/string_view.h> |
| #include <lib/stdcompat/utility.h> |
| |
| #include <gtest/gtest.h> |
| |
| namespace { |
| TEST(InplaceTagTest, InplaceTagsSwitchToStdProvidedOnStd17) { |
| static_assert(std::is_trivially_default_constructible<cpp17::in_place_t>::value); |
| static_assert(std::is_trivially_default_constructible<cpp17::in_place_index_t<0>>::value); |
| static_assert(std::is_trivially_default_constructible<cpp17::in_place_type_t<void>>::value); |
| |
| #if __cplusplus >= 201411L && !defined(LIB_STDCOMPAT_USE_POLYFILLS) |
| static_assert(std::is_same<cpp17::in_place_t, std::in_place_t>::value); |
| static_assert(std::is_same<cpp17::in_place_type_t<void>, std::in_place_type_t<void>>::value); |
| static_assert(std::is_same<cpp17::in_place_index_t<0>, std::in_place_index_t<0>>::value); |
| |
| static_assert(cpp17::addressof(cpp17::in_place) == std::addressof(std::in_place)); |
| static_assert(cpp17::addressof(cpp17::in_place_type<void>) == |
| std::addressof(std::in_place_type<void>)); |
| static_assert(cpp17::addressof(cpp17::in_place_index<0>) == |
| std::addressof(std::in_place_index<0>)); |
| #else // Force template instantiation. |
| |
| // Sanity checks that the instantiations are actually different for the polyfills. |
| static_assert(cpp17::addressof(cpp17::in_place) != nullptr); |
| static_assert(static_cast<const void*>(cpp17::addressof(cpp17::in_place_type<void>)) != |
| static_cast<const void*>(cpp17::addressof(std::in_place_type<int>))); |
| static_assert(static_cast<const void*>(cpp17::addressof(cpp17::in_place_index<0>)) != |
| static_cast<const void*>(cpp17::addressof(std::in_place_index<1>))); |
| #endif |
| } |
| |
| constexpr bool SwapCheck() { |
| int a = 1; |
| int b = 2; |
| |
| cpp20::swap(a, b); |
| |
| return a == 2 && b == 1; |
| } |
| |
| constexpr bool SwapCheck2() { |
| cpp17::string_view a = "1"; |
| cpp17::string_view b = "2"; |
| |
| cpp20::swap(a, b); |
| |
| return a == "2" && b == "1"; |
| } |
| |
| TEST(SwapTest, IsConstexpr) { |
| static_assert(SwapCheck(), "swap evaluates incorrectly in constexpr context."); |
| static_assert(SwapCheck2(), "swap evaluates incorrectly in constexpr context."); |
| } |
| |
| #if __cpp_lib_constexpr_algorithms >= 201806L && !defined(LIB_STDCOMPAT_USE_POLYFILLS) |
| |
| TEST(SwapTest, IsAliasWhenAvailable) { |
| constexpr void (*cpp20_swap)(int&, int&) = &cpp20::swap<int>; |
| constexpr void (*std_swap)(int&, int&) = &std::swap<int>; |
| static_assert(cpp20_swap == std_swap, "cpp20::swap must be an alias for std::swap in c++20."); |
| } |
| |
| #endif |
| |
| template <typename T, typename = void> |
| struct matches_as_const : std::false_type {}; |
| |
| template <typename T> |
| struct matches_as_const<T, cpp17::void_t<decltype(cpp17::as_const(std::declval<T>()))>> |
| : std::true_type {}; |
| |
| template <typename T> |
| static constexpr bool matches_as_const_v = matches_as_const<T>::value; |
| |
| template <typename T> |
| constexpr bool match(T&& value) { |
| return matches_as_const_v<T>; |
| } |
| |
| TEST(AsConstTest, ReturnsConstReference) { |
| int i = 0; |
| const int ci = 0; |
| |
| static_assert(cpp17::is_same_v<decltype(cpp17::as_const(i)), const int&>, ""); |
| static_assert(cpp17::is_same_v<decltype(cpp17::as_const(ci)), const int&>, ""); |
| } |
| |
| TEST(AsConstTest, DeniesRvalueReferences) { |
| int i = 0; |
| const int ci = 0; |
| |
| static_assert(match(i) == true, "cpp17::as_const should accept lvalue references."); |
| static_assert(match(std::move(i)) == false, |
| "cpp17::as_const should not accept rvalue references."); |
| static_assert(match(ci) == true, "cpp17::as_const should accept lvalue references."); |
| static_assert(match(std::move(ci)) == false, |
| "cpp17::as_const should not accept rvalue references."); |
| } |
| |
| #if __cpp_lib_as_const >= 201510L && !defined(LIB_STDCOMPAT_USE_POLYFILLS) |
| |
| TEST(AsConstTest, IsAliasWhenAvailable) { |
| constexpr const int& (*cpp17_as_const)(int&) = &cpp17::as_const<int>; |
| constexpr const int& (*std_as_const)(int&) = &std::as_const<int>; |
| static_assert(cpp17_as_const == std_as_const, |
| "cpp17::as_const must be an alias for std::as_const in c++17."); |
| } |
| |
| #endif |
| |
| } // namespace |