Skip to content

Commit

Permalink
Add non-standard byte_span() creator functions (issue #3, thanks to @…
Browse files Browse the repository at this point in the history
  • Loading branch information
martinmoene committed May 1, 2018
1 parent 63db76f commit 3b4605e
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 6 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ To construct a span from a container with compilers that cannot constrain such a
*span lite* can provide `make_span` creator functions to compensate for the class template argument deduction that is missing from pre-C++17 compilers. See the table below and section [configuration](#configuration).
### `byte_span`
*span lite* can provide `byte_span` creator functions to represent an object as a span of bytes. This requires the C++17 type `std::byte` to be available. See the table below and section [configuration](#configuration).
| Kind | std | Function or method |
|--------------------|------|--------------------|
| **Types** | | **with_container_t** type to disambiguate below constructors |
Expand All @@ -108,10 +113,14 @@ To construct a span from a container with compilers that cannot constrain such a
| &nbsp; | >= C++11 | template&lt;class T, size_t N><br>constexpr span&lt;const T,N><br>**make_span**(std::array&lt;T,N > const & arr) noexcept |
| &nbsp; | >= C++11 | template&lt;class Container><br>constexpr auto<br>**make_span**(Container & cont) -><br>&emsp;span&lt;typename Container::value_type> noexcept |
| &nbsp; | >= C++11 | template&lt;class Container><br>constexpr auto<br>**make_span**(Container const & cont) -><br>&emsp;span&lt;const typename Container::value_type> noexcept |
| &nbsp; | < C++11 | template&lt;class Container><br>span&lt;typename Container::value_type><br>**make_span**( with_container_t, Container & cont ) |
| &nbsp; | < C++11 | template&lt;class Container><br>span&lt;const typename Container::value_type><br>**make_span**( with_container_t, Container const & cont ) |
| &nbsp; | &nbsp; | template&lt;class Container><br>span&lt;typename Container::value_type><br>**make_span**( with_container_t, Container & cont ) |
| &nbsp; | &nbsp; | template&lt;class Container><br>span&lt;const typename Container::value_type><br>**make_span**( with_container_t, Container const & cont ) |
| &nbsp; | < C++11 | template&lt;class T, Allocator><br>span&lt;T><br>**make_span**(std::vector&lt;T, Allocator> & cont) |
| &nbsp; | < C++11 | template&lt;class T, Allocator><br>span&lt;const T><br>**make_span**(std::vector&lt;T, Allocator> const & cont) |
| &nbsp; | &nbsp; | &nbsp; |
| **Free functions**|&nbsp;| macro **`span_CONFIG_PROVIDE_BYTE_SPAN`** |
| &nbsp; | &nbsp; | template&lt;class T><br>span&lt;T, sizeof(T)><br>**byte_span**(T & t) |
| &nbsp; | &nbsp; | template&lt;class T><br>span&lt;const T, sizeof(T)><br>**byte_span**(T const & t) |
Configuration
Expand All @@ -130,6 +139,10 @@ Define this to 1 to select *span lite*'s `nonstd::span`. Default is undefined.
-D<b>span_CONFIG_PROVIDE_MAKE_SPAN</b>=1
Define this to 1 to provide creator functions `nonstd::make_span`. Default is undefined.
### Provide `byte_span` functions
-D<b>span_CONFIG_PROVIDE_BYTE_SPAN</b>=1
Define this to 1 to provide creator functions `nonstd::byte_span`. Default is undefined.
### Contract violation response macros
*span-lite* provides contract violation response control as suggested in proposal [N4415](http://wg21.link/n4415).
Expand Down
34 changes: 34 additions & 0 deletions include/nonstd/span.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,6 +935,8 @@ as_writeable_bytes( span<T,Extent> spn ) span_noexcept
} // namespace span_lite
} // namespace nonstd

// make available in nonstd:

namespace nonstd {

using span_lite::dynamic_extent;
Expand Down Expand Up @@ -1056,10 +1058,42 @@ make_span( with_container_t, Container const & cont ) span_noexcept
} // namespace span_lite
} // namespace nonstd

// make available in nonstd:

namespace nonstd {
using span_lite::make_span;
} // namespace nonstd

#endif // span_CONFIG_PROVIDE_MAKE_SPAN

#if span_CONFIG_PROVIDE_BYTE_SPAN && span_HAVE( BYTE )

namespace nonstd {
namespace span_lite {

template< class T >
inline span_constexpr auto
byte_span( T & t ) span_noexcept -> span< std::byte, sizeof(t) >
{
return span< std::byte, sizeof(t) >( reinterpret_cast< std::byte * >( &t ), sizeof(t) );
}

template< class T >
inline span_constexpr auto
byte_span( T const & t ) span_noexcept -> span< const std::byte, sizeof(t) >
{
return span< const std::byte, sizeof(t) >( reinterpret_cast< std::byte const * >( &t ), sizeof(t) );
}

} // namespace span_lite
} // namespace nonstd

// make available in nonstd:

namespace nonstd {
using span_lite::byte_span;
} // namespace nonstd

#endif // span_CONFIG_PROVIDE_BYTE_SPAN

#endif // NONSTD_SPAN_HPP_INCLUDED
3 changes: 2 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ set( HDRPATH ${HDRDIR}/${HDRNAME} )
set( OPTIONS "" )
set( SPAN_CONFIG
-Dspan_CONFIG_CONTRACT_VIOLATION_THROWS
-Dspan_CONFIG_PROVIDE_MAKE_SPAN=1 )
-Dspan_CONFIG_PROVIDE_MAKE_SPAN=1
-Dspan_CONFIG_PROVIDE_BYTE_SPAN=1 )

set( HAS_STD_FLAGS FALSE )
set( HAS_CPP98_FLAG FALSE )
Expand Down
32 changes: 32 additions & 0 deletions test/span.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,38 @@ CASE( "make_span(): Allows building from a const container (with_container_t, st

#endif // span_CONFIG_PROVIDE_MAKE_SPAN

#if span_CONFIG_PROVIDE_BYTE_SPAN

CASE( "byte_span(): Allows building a span of std::byte from a single object (C++17)" )
{
# if span_HAVE( BYTE )
int x = std::numeric_limits<int>::max();

span<std::byte> spn = byte_span( x );

EXPECT( spn.size() == std::ptrdiff_t( sizeof x ) );
EXPECT( spn[0] == std::byte( 0xff ) );
#else
EXPECT( !!"std::byte is not available (no C++17)" );
#endif
}

CASE( "byte_span(): Allows building a span of const std::byte from a single const object (C++17)" )
{
# if span_HAVE( BYTE )
const int x = std::numeric_limits<int>::max();

span<const std::byte> spn = byte_span( x );

EXPECT( spn.size() == std::ptrdiff_t( sizeof x ) );
EXPECT( spn[0] == std::byte( 0xff ) );
#else
EXPECT( !!"std::byte is not available (no C++17)" );
#endif
}

#endif // span_CONFIG_PROVIDE_BYTE_SPAN

// Issues

#include <cassert>
Expand Down
3 changes: 2 additions & 1 deletion test/t.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ if not "%std%"=="" set std=-std:%std%
::set stdspn=-Dspan_CONFIG_SELECT_STD_SPAN=1 -Dspan_CONFIG_SELECT_NONSTD_SPAN=1
set contract=-Dspan_CONFIG_CONTRACT_VIOLATION_TERMINATES=0 -Dspan_CONFIG_CONTRACT_VIOLATION_THROWS=1
set make_span=-Dspan_CONFIG_PROVIDE_MAKE_SPAN=1
set byte_span=-Dspan_CONFIG_PROVIDE_BYTE_SPAN=1

cl -W3 -EHsc %std% %stdspn% %contract% %make_span% -I../include/nonstd span-main.t.cpp span.t.cpp && span-main.t.exe
cl -W3 -EHsc %std% %stdspn% %contract% %make_span% %byte_span% -DNOMINMAX -I../include/nonstd span-main.t.cpp span.t.cpp && span-main.t.exe
endlocal

3 changes: 2 additions & 1 deletion test/tc.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ if "%std%"=="" set std=c++14
::set stdspn=-Dspan_CONFIG_SELECT_STD_SPAN=1 -Dspan_CONFIG_SELECT_NONSTD_SPAN=1
set contract=-Dspan_CONFIG_CONTRACT_VIOLATION_TERMINATES=0 -Dspan_CONFIG_CONTRACT_VIOLATION_THROWS=1
set make_span=-Dspan_CONFIG_PROVIDE_MAKE_SPAN=1
set byte_span=-Dspan_CONFIG_PROVIDE_BYTE_SPAN=1

set clang=C:\Program Files\LLVM\bin\clang
set flags=-Wpedantic -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-missing-noreturn -Wno-documentation-unknown-command -Wno-documentation-deprecated-sync -Wno-documentation -Wno-weak-vtables -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-exit-time-destructors -Wno-global-constructors

"%clang%" -std=%std% -O2 -Wall -Wextra %flags% %stdspn% %contract% %make_span% -fms-compatibility-version=19.00 -isystem "%VCInstallDir%include" -isystem "%WindowsSdkDir_71A%include" -I../include/nonstd -o span-main.t.exe span-main.t.cpp span.t.cpp && span-main.t.exe
"%clang%" -std=%std% -O2 -Wall -Wextra %flags% %stdspn% %contract% %make_span% %byte_span% -fms-compatibility-version=19.00 -isystem "%VCInstallDir%include" -isystem "%WindowsSdkDir_71A%include" -I../include/nonstd -o span-main.t.exe span-main.t.cpp span.t.cpp && span-main.t.exe
endlocal
3 changes: 2 additions & 1 deletion test/tg.bat
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ if "%std%"=="" set std=c++14
::set stdspn=-Dspan_CONFIG_SELECT_STD_SPAN=1 -Dspan_CONFIG_SELECT_NONSTD_SPAN=1
set contract=-Dspan_CONFIG_CONTRACT_VIOLATION_TERMINATES=0 -Dspan_CONFIG_CONTRACT_VIOLATION_THROWS=1
set make_span=-Dspan_CONFIG_PROVIDE_MAKE_SPAN=1
set byte_span=-Dspan_CONFIG_PROVIDE_BYTE_SPAN=1

set flags=-Wpedantic -Wno-padded -Wno-missing-noreturn
set gpp=g++

%gpp% -std=%std% -O2 -Wall -Wextra %flags% %stdspn% %contract% %make_span% -o span-main.t.exe -I../include/nonstd span-main.t.cpp span.t.cpp && span-main.t.exe
%gpp% -std=%std% -O2 -Wall -Wextra %flags% %stdspn% %contract% %make_span% %byte_span% -o span-main.t.exe -I../include/nonstd span-main.t.cpp span.t.cpp && span-main.t.exe
endlocal

0 comments on commit 3b4605e

Please sign in to comment.