forked from microsoft/STL
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
<algorithm>: Implemented ranges::move (microsoft#888)
Co-authored-by: Casey Carter <Casey@Carter.net>
- Loading branch information
1 parent
732d945
commit 5b29a60
Showing
4 changed files
with
121 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Copyright (c) Microsoft Corporation. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
RUNALL_INCLUDE ..\concepts_matrix.lst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#include <algorithm> | ||
#include <cassert> | ||
#include <concepts> | ||
#include <range_algorithm_support.hpp> | ||
#include <ranges> | ||
#include <utility> | ||
|
||
struct int_wrapper { | ||
int val = 10; | ||
constexpr int_wrapper() = default; | ||
constexpr int_wrapper(int x) : val{x} {} | ||
constexpr int_wrapper(int_wrapper&& that) : val{std::exchange(that.val, -1)} {} | ||
constexpr int_wrapper& operator=(int_wrapper&& that) { | ||
val = std::exchange(that.val, -1); | ||
return *this; | ||
} | ||
}; | ||
|
||
constexpr void smoke_test() { | ||
using ranges::move, ranges::move_result, ranges::iterator_t; | ||
using std::same_as; | ||
|
||
// Validate that move_result aliases in_out_result | ||
STATIC_ASSERT(same_as<move_result<int, double>, ranges::in_out_result<int, double>>); | ||
|
||
// Validate dangling story | ||
STATIC_ASSERT( | ||
same_as<decltype(move(borrowed<false>{}, static_cast<int*>(nullptr))), move_result<ranges::dangling, int*>>); | ||
STATIC_ASSERT(same_as<decltype(move(borrowed<true>{}, static_cast<int*>(nullptr))), move_result<int*, int*>>); | ||
|
||
int const input[] = {13, 53, 12435}; | ||
{ | ||
int output[] = {-2, -2, -2}; | ||
auto result = move(move_only_range{input}, move_only_range{output}.begin()); | ||
STATIC_ASSERT(same_as<decltype(result), | ||
move_result<iterator_t<move_only_range<int const>>, iterator_t<move_only_range<int>>>>); | ||
assert(result.in == move_only_range{input}.end()); | ||
assert(result.out == move_only_range{output}.end()); | ||
assert(ranges::equal(output, input)); | ||
} | ||
{ | ||
int output[] = {-2, -2, -2}; | ||
move_only_range wrapped_input{input}; | ||
auto result = move(wrapped_input.begin(), wrapped_input.end(), move_only_range{output}.begin()); | ||
STATIC_ASSERT(same_as<decltype(result), | ||
move_result<iterator_t<move_only_range<int const>>, iterator_t<move_only_range<int>>>>); | ||
assert(result.in == wrapped_input.end()); | ||
assert(result.out == move_only_range{output}.end()); | ||
assert(ranges::equal(output, input)); | ||
} | ||
{ | ||
int_wrapper input1[3] = {13, 55, 1234}; | ||
int const expected_output[3] = {13, 55, 1234}; | ||
int_wrapper actual_output[3] = {-2, -2, -2}; | ||
move_only_range wrapped_input{input1}; | ||
auto result = move(wrapped_input.begin(), wrapped_input.end(), move_only_range{actual_output}.begin()); | ||
assert(result.in == wrapped_input.end()); | ||
assert(result.out == move_only_range{actual_output}.end()); | ||
for (int i = 0; i < 3; ++i) { | ||
assert(input1[i].val == -1); | ||
assert(actual_output[i].val == expected_output[i]); | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
STATIC_ASSERT((smoke_test(), true)); | ||
smoke_test(); | ||
} | ||
|
||
struct instantiator { | ||
template <class In, class Out> | ||
static void call(In&& in = {}, Out out = {}) { | ||
(void) ranges::move(in, std::move(out)); | ||
(void) ranges::move(ranges::begin(in), ranges::end(in), std::move(out)); | ||
} | ||
}; | ||
|
||
template void test_in_write<instantiator>(); |