mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Added span to object rep conversions.
This commit is contained in:
parent
d63c9803da
commit
ba8ebef509
33
include/byte.h
Normal file
33
include/byte.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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_BYTE_H
|
||||||
|
#define GSL_BYTE_H
|
||||||
|
|
||||||
|
namespace gsl
|
||||||
|
{
|
||||||
|
// This is a simple definition for now that allows
|
||||||
|
// use of byte within span<> to be standards-compliant
|
||||||
|
//
|
||||||
|
// Ultimately a small language change would allow a more
|
||||||
|
// robust definition (see WG21 proposal P0257 for details).
|
||||||
|
using byte = unsigned char;
|
||||||
|
|
||||||
|
} // namespace gsl
|
||||||
|
|
||||||
|
#endif // GSL_BYTE_H
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h"
|
#include "gsl_assert.h"
|
||||||
#include "gsl_util.h"
|
#include "gsl_util.h"
|
||||||
|
#include "byte.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -1053,9 +1054,6 @@ template <typename Span>
|
|||||||
class contiguous_span_iterator;
|
class contiguous_span_iterator;
|
||||||
template <typename Span>
|
template <typename Span>
|
||||||
class general_span_iterator;
|
class general_span_iterator;
|
||||||
enum class byte : std::uint8_t
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <std::ptrdiff_t DimSize = dynamic_range>
|
template <std::ptrdiff_t DimSize = dynamic_range>
|
||||||
struct dim
|
struct dim
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "gsl_assert.h"
|
#include "gsl_assert.h"
|
||||||
#include "gsl_util.h"
|
#include "gsl_util.h"
|
||||||
|
#include "byte.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
@ -126,13 +127,13 @@ struct is_allowed_element_type_conversion
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <class From>
|
template <class From>
|
||||||
struct is_allowed_element_type_conversion<From, char>
|
struct is_allowed_element_type_conversion<From, byte>
|
||||||
: std::integral_constant<bool, !std::is_const<From>::value>
|
: std::integral_constant<bool, !std::is_const<From>::value>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class From>
|
template <class From>
|
||||||
struct is_allowed_element_type_conversion<From, const char>
|
struct is_allowed_element_type_conversion<From, const byte>
|
||||||
: std::integral_constant<bool, true>
|
: std::integral_constant<bool, true>
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -507,14 +508,33 @@ constexpr bool operator>=(const span<ElementType, Extent>& l, const span<Element
|
|||||||
{ return !(l < r); }
|
{ return !(l < r); }
|
||||||
|
|
||||||
|
|
||||||
#if 0 // TODO
|
namespace details
|
||||||
|
{
|
||||||
|
// if we only supported compilers with good constexpr support then
|
||||||
|
// this pair of classes could collapse down to a constexpr function
|
||||||
|
|
||||||
|
// we should use a narrow_cast<> to go to size_t, but older compilers may not see it as constexpr
|
||||||
|
// and so will fail compilation of the template
|
||||||
|
template <class ElementType, ptrdiff_t Extent>
|
||||||
|
struct calculate_byte_size :
|
||||||
|
std::integral_constant<std::ptrdiff_t, static_cast<ptrdiff_t>(sizeof(ElementType) * static_cast<size_t>(Extent))>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template <class ElementType>
|
||||||
|
struct calculate_byte_size<ElementType, dynamic_extent> :
|
||||||
|
std::integral_constant<std::ptrdiff_t, dynamic_extent>
|
||||||
|
{};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// [span.objectrep], views of object representation
|
// [span.objectrep], views of object representation
|
||||||
template <class ElementType, ptrdiff_t Extent>
|
template <class ElementType, ptrdiff_t Extent>
|
||||||
constexpr span<const char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
|
constexpr span<const byte, details::calculate_byte_size<ElementType, Extent>::value> as_bytes(span<ElementType, Extent> s) noexcept
|
||||||
|
{ return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; }
|
||||||
|
|
||||||
template <class ElementType, ptrdiff_t Extent>
|
template <class ElementType, ptrdiff_t Extent, class = std::enable_if_t<!std::is_const<ElementType>::value>>
|
||||||
constexpr span<char, ((Extent == dynamic_extent) ? dynamic_extent : (sizeof(ElementType) * Extent))> as_writeable_bytes(span<ElementType, Extent>) noexcept;
|
constexpr span<byte, details::calculate_byte_size<ElementType, Extent>::value> as_writeable_bytes(span<ElementType, Extent> s) noexcept
|
||||||
#endif
|
{ return {reinterpret_cast<byte*>(s.data()), s.size_bytes()}; }
|
||||||
|
|
||||||
} // namespace gsl
|
} // namespace gsl
|
||||||
|
|
||||||
|
@ -921,6 +921,69 @@ SUITE(span_tests)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(as_bytes)
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
|
{
|
||||||
|
span<const int> s = a;
|
||||||
|
CHECK(s.length() == 4);
|
||||||
|
span<const byte> bs = as_bytes(s);
|
||||||
|
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||||
|
CHECK(bs.length() == s.length_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
span<int> s;
|
||||||
|
auto bs = as_bytes(s);
|
||||||
|
CHECK(bs.length() == s.length());
|
||||||
|
CHECK(bs.length() == 0);
|
||||||
|
CHECK(bs.size_bytes() == 0);
|
||||||
|
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||||
|
CHECK(bs.data() == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
span<int> s = a;
|
||||||
|
auto bs = as_bytes(s);
|
||||||
|
CHECK(static_cast<const void*>(bs.data()) == static_cast<const void*>(s.data()));
|
||||||
|
CHECK(bs.length() == s.length_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(as_writeable_bytes)
|
||||||
|
{
|
||||||
|
int a[] = {1, 2, 3, 4};
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifdef CONFIRM_COMPILATION_ERRORS
|
||||||
|
// you should not be able to get writeable bytes for const objects
|
||||||
|
span<const int> s = a;
|
||||||
|
CHECK(s.length() == 4);
|
||||||
|
span<const byte> bs = as_writeable_bytes(s);
|
||||||
|
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
|
CHECK(bs.length() == s.length_bytes());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
span<int> s;
|
||||||
|
auto bs = as_writeable_bytes(s);
|
||||||
|
CHECK(bs.length() == s.length());
|
||||||
|
CHECK(bs.length() == 0);
|
||||||
|
CHECK(bs.size_bytes() == 0);
|
||||||
|
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
|
CHECK(bs.data() == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
span<int> s = a;
|
||||||
|
auto bs = as_writeable_bytes(s);
|
||||||
|
CHECK(static_cast<void*>(bs.data()) == static_cast<void*>(s.data()));
|
||||||
|
CHECK(bs.length() == s.length_bytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
TEST(fixed_size_conversions)
|
TEST(fixed_size_conversions)
|
||||||
{
|
{
|
||||||
@ -1018,34 +1081,6 @@ SUITE(span_tests)
|
|||||||
CHECK_THROW(f(), fail_fast);
|
CHECK_THROW(f(), fail_fast);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(as_writeable_bytes)
|
|
||||||
{
|
|
||||||
int a[] = {1, 2, 3, 4};
|
|
||||||
|
|
||||||
{
|
|
||||||
#ifdef CONFIRM_COMPILATION_ERRORS
|
|
||||||
// you should not be able to get writeable bytes for const objects
|
|
||||||
span<const int, dynamic_range> av = a;
|
|
||||||
auto wav = av.as_writeable_bytes();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
span<int, dynamic_range> av;
|
|
||||||
auto wav = as_writeable_bytes(av);
|
|
||||||
CHECK(wav.length() == av.length());
|
|
||||||
CHECK(wav.length() == 0);
|
|
||||||
CHECK(wav.size_bytes() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
span<int, dynamic_range> av = a;
|
|
||||||
auto wav = as_writeable_bytes(av);
|
|
||||||
CHECK(wav.data() == (byte*) &a[0]);
|
|
||||||
CHECK(wav.length() == sizeof(a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user