brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 6c7d194 Raw
154 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// _Tp* __constexpr_memmove(_Tp* __dest, _Up* __src, __element_count __n);10//11// General tests for __constexpr_memmove.12//13// In particular, we try to ensure that __constexpr_memmove behaves like14// __builtin_memmove as closely as possible. This means that it produces the15// same effect, but also that it has the same type requirements.16//17// __builtin_memmove only requires that the types are TriviallyCopyable18// (which is interestingly different from both is_trivially_XXX_constructible19// and is_trivially_XXX_assignable), so we use some funky types to test these20// corner cases.21 22#include <__cxx03/__string/constexpr_c_functions.h>23#include <cassert>24#include <cstdint>25#include <type_traits>26 27#include "test_macros.h"28 29// The following types are all TriviallyCopyable, but they are not all30// trivially_{copy,move}_{constructible,assignable}. TriviallyCopyable31// guarantees that the type is *at least* one of the four, but no more32// than that.33struct CopyConstructible {34  CopyConstructible() = default;35  int value           = 0;36 37  CopyConstructible(const CopyConstructible&)            = default;38  CopyConstructible(CopyConstructible&&)                 = delete;39  CopyConstructible& operator=(const CopyConstructible&) = delete;40  CopyConstructible& operator=(CopyConstructible&&)      = delete;41};42 43struct MoveConstructible {44  MoveConstructible() = default;45  int value           = 0;46 47  MoveConstructible(const MoveConstructible&)            = delete;48  MoveConstructible(MoveConstructible&&)                 = default;49  MoveConstructible& operator=(const MoveConstructible&) = delete;50  MoveConstructible& operator=(MoveConstructible&&)      = delete;51};52 53struct CopyAssignable {54  CopyAssignable() = default;55  int value        = 0;56 57  CopyAssignable(const CopyAssignable&)            = delete;58  CopyAssignable(CopyAssignable&&)                 = delete;59  CopyAssignable& operator=(const CopyAssignable&) = default;60  CopyAssignable& operator=(CopyAssignable&&)      = delete;61};62 63struct MoveAssignable {64  MoveAssignable() = default;65  int value        = 0;66 67  MoveAssignable(const MoveAssignable&)            = delete;68  MoveAssignable(MoveAssignable&&)                 = delete;69  MoveAssignable& operator=(const MoveAssignable&) = delete;70  MoveAssignable& operator=(MoveAssignable&&)      = default;71};72 73template <class Source, class Dest>74TEST_CONSTEXPR_CXX14 void test_user_defined_types() {75  static_assert(std::is_trivially_copyable<Source>::value, "test the test");76  static_assert(std::is_trivially_copyable<Dest>::value, "test the test");77 78  // Note that we can't just initialize with an initializer list since some of the types we use here79  // are not copy-constructible, which is required in pre-C++20 Standards for that syntax to work.80  Source src[3];81  src[0].value = 1;82  src[1].value = 2;83  src[2].value = 3;84  Dest dst[3];85  dst[0].value = 111;86  dst[1].value = 111;87  dst[2].value = 111;88 89  Dest* result = std::__constexpr_memmove(dst, src, std::__element_count(3));90  assert(result == dst);91  assert(dst[0].value == 1);92  assert(dst[1].value == 2);93  assert(dst[2].value == 3);94}95 96template <class Source, class Dest>97TEST_CONSTEXPR_CXX14 void test_builtin_types() {98  Source src[3] = {1, 2, 3};99  Dest dst[3]   = {111, 111, 111};100 101  Dest* result = std::__constexpr_memmove(dst, src, std::__element_count(3));102  assert(result == dst);103  assert(dst[0] == 1);104  assert(dst[1] == 2);105  assert(dst[2] == 3);106}107 108template <class SourcePtr, class DestPtr, class ObjectType>109TEST_CONSTEXPR_CXX14 void test_pointer_types() {110  ObjectType objs[3] = {1, 2, 3};111 112  SourcePtr src[3] = {objs + 0, objs + 1, objs + 2};113  DestPtr dst[3]   = {nullptr, nullptr, nullptr};114 115  DestPtr* result = std::__constexpr_memmove(dst, src, std::__element_count(3));116  assert(result == dst);117  assert(dst[0] == objs + 0);118  assert(dst[1] == objs + 1);119  assert(dst[2] == objs + 2);120}121 122TEST_CONSTEXPR_CXX14 bool test() {123  test_user_defined_types<CopyConstructible, CopyConstructible>();124  test_user_defined_types<MoveConstructible, MoveConstructible>();125  test_user_defined_types<CopyAssignable, CopyAssignable>();126  test_user_defined_types<MoveAssignable, MoveAssignable>();127 128  test_builtin_types<char, char>();129  test_builtin_types<short, short>();130  test_builtin_types<int, int>();131  test_builtin_types<long, long>();132  test_builtin_types<long long, long long>();133 134  // Cross-type135  test_builtin_types<std::int16_t, std::uint16_t>();136  test_builtin_types<std::int16_t, char16_t>();137  test_builtin_types<std::int32_t, std::uint32_t>();138  test_builtin_types<std::int32_t, char32_t>();139 140  test_pointer_types<char*, char*, char>();141  test_pointer_types<int*, int*, int>();142  test_pointer_types<long*, long*, long>();143  test_pointer_types<void*, void*, int>();144  test_pointer_types<int* const, int*, int>();145 146  return true;147}148 149int main(int, char**) {150  test();151 152  return 0;153}154