mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Add a copy() function for span.
This commit is contained in:
parent
2df9f85385
commit
d2dafe2ddf
@ -10,6 +10,7 @@ set(GSL_HEADERS
|
|||||||
"gsl/multi_span"
|
"gsl/multi_span"
|
||||||
"gsl/span"
|
"gsl/span"
|
||||||
"gsl/string_span"
|
"gsl/string_span"
|
||||||
|
"gsl/gsl_algorithm"
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
|
61
gsl/gsl_algorithm
Normal file
61
gsl/gsl_algorithm
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// This code is licensed under the MIT License (MIT).
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef GSL_ALGORITHM_H
|
||||||
|
#define GSL_ALGORITHM_H
|
||||||
|
|
||||||
|
#include "span"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
|
||||||
|
// turn off some warnings that are noisy about our Expects statements
|
||||||
|
#pragma warning(disable : 4127) // conditional expression is constant
|
||||||
|
|
||||||
|
// blanket turn off warnings from CppCoreCheck for now
|
||||||
|
// so people aren't annoyed by them when running the tool.
|
||||||
|
// more targeted suppressions will be added in a future update to the GSL
|
||||||
|
#pragma warning(disable : 26481 26482 26483 26485 26490 26491 26492 26493 26495)
|
||||||
|
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
namespace gsl
|
||||||
|
{
|
||||||
|
|
||||||
|
template <class SrcElementType, std::ptrdiff_t SrcExtent,
|
||||||
|
class DestElementType, std::ptrdiff_t DestExtent>
|
||||||
|
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
|
||||||
|
{
|
||||||
|
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
|
||||||
|
"Elements of source span can not be assigned to elements of destination span");
|
||||||
|
static_assert(SrcExtent == dynamic_extent || DestExtent == dynamic_extent || (SrcExtent <= DestExtent),
|
||||||
|
"Source range is longer than target range");
|
||||||
|
|
||||||
|
Expects(dest.size() >= src.size());
|
||||||
|
std::copy_n(src.data(), src.size(), dest.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gsl
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif // _MSC_VER
|
||||||
|
|
||||||
|
#endif // GSL_ALGORITHM_H
|
@ -52,3 +52,5 @@ add_gsl_test(assertion_tests)
|
|||||||
add_gsl_test(utils_tests)
|
add_gsl_test(utils_tests)
|
||||||
add_gsl_test(owner_tests)
|
add_gsl_test(owner_tests)
|
||||||
add_gsl_test(byte_tests)
|
add_gsl_test(byte_tests)
|
||||||
|
add_gsl_test(algorithm_tests)
|
||||||
|
|
||||||
|
209
tests/algorithm_tests.cpp
Normal file
209
tests/algorithm_tests.cpp
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
|
//
|
||||||
|
// This code is licensed under the MIT License (MIT).
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <UnitTest++/UnitTest++.h>
|
||||||
|
#include <gsl/gsl_algorithm>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace gsl;
|
||||||
|
|
||||||
|
SUITE(copy_tests)
|
||||||
|
{
|
||||||
|
|
||||||
|
TEST(same_type)
|
||||||
|
{
|
||||||
|
// dynamic source and destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<int, 10> dst{};
|
||||||
|
|
||||||
|
span<int> src_span(src);
|
||||||
|
span<int> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static source and dynamic destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<int, 10> dst{};
|
||||||
|
|
||||||
|
span<int, 5> src_span(src);
|
||||||
|
span<int> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamic source and static destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<int, 10> dst{};
|
||||||
|
|
||||||
|
span<int> src_span(src);
|
||||||
|
span<int, 10> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static source and destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<int, 10> dst{};
|
||||||
|
|
||||||
|
span<int, 5> src_span(src);
|
||||||
|
span<int, 10> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(compatible_type)
|
||||||
|
{
|
||||||
|
// dynamic source and destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<char, 10> dst{};
|
||||||
|
|
||||||
|
span<int> src_span(src);
|
||||||
|
span<char> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static source and dynamic destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<char, 10> dst{};
|
||||||
|
|
||||||
|
span<int, 5> src_span(src);
|
||||||
|
span<char> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamic source and static destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<char, 10> dst{};
|
||||||
|
|
||||||
|
span<int> src_span(src);
|
||||||
|
span<char, 10> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static source and destination span
|
||||||
|
{
|
||||||
|
std::array<int, 5> src{1, 2, 3, 4, 5};
|
||||||
|
std::array<char, 10> dst{};
|
||||||
|
|
||||||
|
span<int, 5> src_span(src);
|
||||||
|
span<char, 10> dst_span(dst);
|
||||||
|
|
||||||
|
copy(src_span, dst_span);
|
||||||
|
copy(src_span, dst_span.subspan(src_span.size()));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < src.size(); ++i) {
|
||||||
|
CHECK(dst[i] == src[i]);
|
||||||
|
CHECK(dst[i + src.size()] == src[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
|
TEST(incompatible_type)
|
||||||
|
{
|
||||||
|
std::array<int, 4> src{1, 2, 3, 4};
|
||||||
|
std::array<int*, 12> dst{};
|
||||||
|
|
||||||
|
span<int> src_span_dyn(src);
|
||||||
|
span<int, 4> src_span_static(src);
|
||||||
|
span<int*> dst_span_dyn(dst);
|
||||||
|
span<int*, 4> dst_span_static(dst);
|
||||||
|
|
||||||
|
// every line should produce a compilation error
|
||||||
|
copy(src_span_dyn, dst_span_dyn);
|
||||||
|
copy(src_span_dyn, dst_span_static);
|
||||||
|
copy(src_span_static, dst_span_dyn);
|
||||||
|
copy(src_span_static, dst_span_static);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST(small_destination_span)
|
||||||
|
{
|
||||||
|
std::array<int, 12> src{1, 2, 3, 4};
|
||||||
|
std::array<int, 4> dst{};
|
||||||
|
|
||||||
|
span<int> src_span_dyn(src);
|
||||||
|
span<int, 12> src_span_static(src);
|
||||||
|
span<int> dst_span_dyn(dst);
|
||||||
|
span<int, 4> dst_span_static(dst);
|
||||||
|
|
||||||
|
CHECK_THROW(copy(src_span_dyn, dst_span_dyn), fail_fast);
|
||||||
|
CHECK_THROW(copy(src_span_dyn, dst_span_static), fail_fast);
|
||||||
|
CHECK_THROW(copy(src_span_static, dst_span_dyn), fail_fast);
|
||||||
|
|
||||||
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
|
copy(src_span_static, dst_span_static);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int, const char* []) { return UnitTest::RunAllTests(); }
|
Loading…
Reference in New Issue
Block a user