brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · fe0b7ad Raw
107 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// UNSUPPORTED: c++0310 11// <algorithm>12 13// We optimize std::copy(_backward) and std::move(_backward) into memmove14// when the iterator is trivial and contiguous and the type in question15// is also trivially (copyable, movable). This test verifies that the16// optimization never eliminates an actually non-trivial copy or move.17 18#include <algorithm>19#include <iterator>20#include <cassert>21 22#include "test_macros.h"23#include "test_iterators.h"24 25struct TMBNTC {26    int *p;27    constexpr TMBNTC(int& copies) : p(&copies) {}28    constexpr TMBNTC(const TMBNTC&) = default;29    TEST_CONSTEXPR_CXX14 TMBNTC& operator=(TMBNTC&&) = default;30    TEST_CONSTEXPR_CXX14 TMBNTC& operator=(const TMBNTC&) { ++*p; return *this; }31};32 33TEST_CONSTEXPR_CXX20 bool34test_trivial_moveassign_but_no_trivial_copyassign()35{36    int copies = 0;37    TMBNTC ia[] = { copies, copies, copies, copies };38    TMBNTC ib[] = { copies, copies, copies, copies };39    std::copy(ia, ia+4, ib);40    assert(copies == 4);41    copies = 0;42    std::copy_backward(ia, ia+4, ib+4);43    assert(copies == 4);44 45    copies = 0;46    std::copy(std::make_move_iterator(ia), std::make_move_iterator(ia+4), ib);47    assert(copies == 0);48    std::copy_backward(std::make_move_iterator(ia), std::make_move_iterator(ia+4), ib+4);49    assert(copies == 0);50 51    std::move(ia, ia+4, ib);52    assert(copies == 0);53    std::move_backward(ia, ia+4, ib+4);54    assert(copies == 0);55 56    return true;57}58 59struct TCBNTM {60    int *p;61    constexpr TCBNTM(int& moves) : p(&moves) {}62    constexpr TCBNTM(const TCBNTM&) = default;63    TEST_CONSTEXPR_CXX14 TCBNTM& operator=(TCBNTM&&) { ++*p; return *this; }64    TEST_CONSTEXPR_CXX14 TCBNTM& operator=(const TCBNTM&) = default;65};66 67TEST_CONSTEXPR_CXX20 bool68test_trivial_copyassign_but_no_trivial_moveassign()69{70    int moves = 0;71    TCBNTM ia[] = { moves, moves, moves, moves };72    TCBNTM ib[] = { moves, moves, moves, moves };73    std::move(ia, ia+4, ib);74    assert(moves == 4);75    moves = 0;76    std::move_backward(ia, ia+4, ib+4);77    assert(moves == 4);78 79    moves = 0;80    std::copy(std::make_move_iterator(ia), std::make_move_iterator(ia+4), ib);81    assert(moves == 4);82    moves = 0;83    std::copy_backward(std::make_move_iterator(ia), std::make_move_iterator(ia+4), ib+4);84    assert(moves == 4);85 86    moves = 0;87    std::copy(ia, ia+4, ib);88    assert(moves == 0);89    std::copy_backward(ia, ia+4, ib+4);90    assert(moves == 0);91 92    return true;93}94 95int main(int, char**)96{97    test_trivial_moveassign_but_no_trivial_copyassign();98    test_trivial_copyassign_but_no_trivial_moveassign();99 100#if TEST_STD_VER > 17101    static_assert(test_trivial_moveassign_but_no_trivial_copyassign());102    static_assert(test_trivial_copyassign_but_no_trivial_moveassign());103#endif104 105    return 0;106}107