Compare commits

..

289 Commits

Author SHA1 Message Date
Jordan Maples [MSFT] 1999b48a51 Merge pull request #870 from beinhaerter/suppress_span_warning
suppress code analysis warning
2020-04-23 10:13:33 -07:00
Jordan Maples [MSFT] 3da256d03b Merge pull request #874 from JordanMaples/dev/jomaples/multi_span-cleanup
Minor changes to multi_span
2020-04-23 10:13:04 -07:00
Jordan Maples [MSFT] 601b55ea61 Merge pull request #873 from londey/narrow-throw
Changed implementation of gsl::narrow to throw gsl::narrowing_error
2020-04-22 22:57:14 -07:00
Nicholas Londey 3a5b83db35 Removed unused contant from test 2020-04-23 12:30:44 +10:00
Nicholas Londey 94d6a35726 Fixed narrow unit test EXPECT_THROW 2020-04-23 12:23:36 +10:00
Nicholas Londey 14acdcd7a8 Removed unused #include 2020-04-23 12:22:30 +10:00
Nicholas Londey 4eb554d7c2 Removed no_exception_throw_tests.cpp
as per review feedback
2020-04-23 11:58:00 +10:00
Jordan Maples [MSFT] 70e1317ab6 Update include/gsl/gsl 2020-04-22 15:27:00 -07:00
Nicholas Londey 61534ca3ad Changed implementation of gsl::narrow to throw gsl::narrowing_error
Implementation now behaves as described in the C++ Core Guidlines
2020-04-22 10:09:13 +10:00
Jordan Maples afa2f3fd9a fully qualify ptrdiff_t in multi_span and remove it from gsl\gsl 2020-04-21 16:14:58 -07:00
Werner Henze fb1243d735 suppress code analysis warning
- suppress " warning C26481: Don't use pointer arithmetic. Use span instead (bounds.1)."
- Please note that the suppression in `end()` does not work with MSVC 16.5.4.
2020-04-19 16:41:12 +02:00
Jordan Maples [MSFT] 9f6a9a5807 Merge pull request #867 from xvitaly/fix-cmake-install
Fixed installation on GNU/Linux distributions
2020-04-17 10:18:37 -07:00
Vitaly Zaitsev aeb65efada Fixed installation on GNU/Linux distributions.
Signed-off-by: Vitaly Zaitsev <vitaly@easycoding.org>
2020-04-17 11:47:23 +02:00
Jordan Maples [MSFT] b43855631a Merge pull request #861 from JordanMaples/dev/jomaples/lwg3320
implement LWG3320
2020-04-15 10:00:55 -07:00
Jordan Maples 9cb376c050 adding back free functions for [c|cr][begin|end] 2020-04-14 16:57:12 -07:00
Jordan Maples 7341c5d1b5 implement LWG3320 by deleting const_iterator and const_reverse_iterator 2020-04-14 13:51:49 -07:00
Jordan Maples [MSFT] 044849d6fa Merge pull request #823 from RedDwarf69/std_byte_fix
Add missing #include if built with GSL_USE_STD_BYTE=1
2020-04-13 11:33:56 -07:00
Jordan Maples [MSFT] 24dc828cbb Merge pull request #860 from karzhenkov/fix-googletest-link
Fix link to Google Test
2020-04-13 10:35:19 -07:00
Alexander Karzhenkov 8b8c25fa66 Fix link to Google Test 2020-04-13 18:19:51 +05:00
Jordan Maples [MSFT] f7aae78ff6 Merge pull request #854 from JordanMaples/dev/jomaples/LWG3255
Implement span std::array ctor changes from LWG3255
2020-04-09 23:42:04 -07:00
Jordan Maples efbce17ca4 testing one of CaseyCarter's comments 2020-04-09 17:33:33 -07:00
Jordan Maples ffbfcc0a9f apply clang-format to the span_compatibility_tests. 2020-04-09 16:15:08 -07:00
Jordan Maples 5ca02327c4 another test 2020-04-09 15:56:26 -07:00
Jordan Maples 8d907dadfb prevent comparison for apple clang versions older than 11 2020-04-09 14:35:44 -07:00
Jordan Maples b7d9d754ac another attempt at apple clang version filtering 2020-04-09 14:17:52 -07:00
Jordan Maples 809aee2315 testing different major/minor for Apple suppression 2020-04-09 11:51:59 -07:00
Jordan Maples 6ef56d73da fixed a couple typos 2020-04-09 10:35:44 -07:00
Jordan Maples 2f9d873043 added additional filtering to Apple clang versions 9.4 and 10.1 for the ArrayConvertibilityCheck 2020-04-09 10:34:58 -07:00
Jordan Maples f85166aa8b Merge branch 'master' into dev/jomaples/LWG3255 2020-04-09 09:53:45 -07:00
Jordan Maples [MSFT] b0b933b842 Merge pull request #858 from Farwaykorse/patch-1
Solve MSVC warning C4668: __GNUC__ & __clang__ not defined
2020-04-08 23:21:08 -07:00
Jordan Maples [MSFT] bc7ea7aac7 Merge pull request #859 from Farwaykorse/patch-2
Suppress GCC 8 "-Warray-bounds" warning
2020-04-08 23:20:44 -07:00
Farwaykorse 611674d60b GCC "-Warray-bounds" warning persists with release 8.4
modification of commit 5e21831494
2020-04-09 03:50:17 +02:00
Farwaykorse 6e2398b524 Solve MSVC warning C4668: __GNUC__ & __clang__ not defined as a preprocessor macro
MSVC compiler warning C4668:
` '__clang__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'`
2020-04-09 03:15:57 +02:00
Jordan Maples ff45864dba Merge branch 'dev/jomaples/LWG3255' of https://github.com/JordanMaples/GSL into dev/jomaples/LWG3255 2020-04-08 14:48:05 -07:00
Jordan Maples 15dd17aa5b Merge branch 'master' into dev/jomaples/LWG3255 2020-04-08 14:47:08 -07:00
Jordan Maples [MSFT] c5dd0e6d40 Merge pull request #3 from JordanMaples/dev/jomaples/lwg3255
adding additional filtering
2020-04-08 14:43:15 -07:00
Jordan Maples 01d206f4d8 adding additional filtering 2020-04-08 14:38:01 -07:00
Jordan Maples [MSFT] 226a854a97 Merge pull request #835 from Farwaykorse/TravisCI
Improve CI with TravisCI
2020-03-26 15:00:27 -07:00
Roelf-Jilling 5e21831494 Suppress test for GCC 8.3 triggering "-Warray-bounds" 2020-03-26 20:15:29 +01:00
Roelf-Jilling 04809f8559 TravisCI: moved "based on" comment to relevant legacy section 2020-03-26 17:16:32 +01:00
Roelf-Jilling 511faf07d4 TravisCI: remove deprecated key "sudo" and replace alias "matrix" for "jobs" 2020-03-26 17:04:01 +01:00
Roelf-Jilling 610c40333d TravisCI: add Clang-10 2020-03-26 16:29:27 +01:00
Roelf-Jilling 30c068781f Merge branch 'master' into TravisCI 2020-03-26 16:24:19 +01:00
Roelf-Jilling f4c2292f9d Update to use the latest CMake releases
3.17.0, 3.16.5 and 3.15.7
2020-03-26 16:12:07 +01:00
Jordan Maples [MSFT] 0357a02921 Apply suggestions from code review
Committing suggested change: XCode to Xcode

Co-Authored-By: Kevin Wojniak <kainjow@users.noreply.github.com>
2020-03-23 13:57:46 -07:00
Jordan Maples ddde9e153d update convertibility test 2020-03-19 14:08:04 -07:00
Jordan Maples 6eab19d3c1 moving decl so we dont get the stl_nullptr is not used warning 2020-03-17 15:13:26 -07:00
Jordan Maples f8bcb7d9eb applied clang-format 2020-03-17 15:04:58 -07:00
Jordan Maples 9b3ac8d681 discussed the issue with Casey Carter, the span ctor changes are accurate but the tests are not. The test require work that was done in C++17 regarding qualifier conversions to work correctly. Scoping tests for 17. 2020-03-17 15:02:00 -07:00
Jordan Maples 1dd1320c8b test commit to get extra eyes on the problem 2020-03-17 13:53:13 -07:00
Jordan Maples [MSFT] d90fefea6d Merge pull request #851 from JordanMaples/dev/jomaples/exception
prevent exception include when in no-exception mode.
2020-03-17 13:41:33 -07:00
Jordan Maples 06adf557e9 update kernel mode detection macro 2020-03-12 12:32:32 -07:00
Jordan Maples ce4d689f4f shuffle around code to bring includes to top. 2020-03-06 11:22:09 -08:00
Jordan Maples b30524088a added some comments and ran clang-format 2020-03-06 11:17:58 -08:00
Jordan Maples 769f01900d moving exception include 2020-03-03 17:04:46 -08:00
Jordan Maples [MSFT] 4b643918a1 Merge pull request #784 from hanst99/hunterization
Update "Make library importable by CMake using find_package"
2020-02-26 08:48:04 -08:00
Jordan Maples [MSFT] a3b86971d9 Merge pull request #847 from JordanMaples/dev/jomaples/split_span
Removing non-standard functionality from span header. Use span_ext for span comparisons and make_span functionality.
2020-02-25 16:59:54 -08:00
Jordan Maples [MSFT] 4a6a7a095d add back array header, will remove in separate pr 2020-02-25 14:09:29 -08:00
Jordan Maples [MSFT] d2fdeda06e Merge branch 'dev/jomaples/split_span' of https://github.com/jordanmaples/gsl into dev/jomaples/split_span 2020-02-25 13:53:00 -08:00
Jordan Maples [MSFT] fc54e0d89a just pulling in array header if we detect apple clang 2020-02-25 13:39:47 -08:00
Jordan Maples [MSFT] 5d54cada8e just pulling in array header if we detect apple clang 2020-02-24 15:49:30 -08:00
Jordan Maples [MSFT] 32e5fea6ac test 2020-02-24 14:47:45 -08:00
Jordan Maples [MSFT] 0f60c68ab9 disgusting test to get apple clang to work, dont look at it 2020-02-24 14:41:29 -08:00
Jordan Maples [MSFT] 60372b6468 apple-clang failed again, forcing class instead of struct 2020-02-24 13:43:42 -08:00
Jordan Maples [MSFT] 89271b89c1 fix apple clang forward declaration 2020-02-24 13:06:01 -08:00
Jordan Maples [MSFT] ac37004274 clang defines struct as array where msvc and g++ define it as class. 2020-02-24 11:45:33 -08:00
Jordan Maples [MSFT] 3144082909 forward declare span and remove header 2020-02-24 11:16:26 -08:00
Jordan Maples [MSFT] c853017be3 forgot nl @ eof in span_ext_tests.cpp 2020-02-19 14:44:22 -08:00
Jordan Maples [MSFT] 94f43d4adf splitting up span's standard and non-standard behavior 2020-02-19 14:28:12 -08:00
Jordan Maples [MSFT] 691a78c016 Merge pull request #844 from JordanMaples/dev/jomaples/unsigned
gsl::span: Migrate from signed to unsigned
2020-02-18 16:55:14 -08:00
Jordan Maples [MSFT] 46603698ec rewrite operators in iterator to take advantage of nrvo 2020-02-18 15:36:15 -08:00
Jordan Maples [MSFT] f4c608fd39 addressing comments 2020-02-18 14:09:11 -08:00
Jordan Maples [MSFT] 8ba6cb1074 Merge branch 'dev/jomaples/unsigned' of https://github.com/jordanmaples/gsl into dev/jomaples/unsigned 2020-02-18 10:13:14 -08:00
Jordan Maples [MSFT] 8d6ca323fa GTest latest is breaking, rolling back to 1.10 until further investigation 2020-02-18 10:13:03 -08:00
Jordan Maples [MSFT] 6b01a0488b Update span_compatibility_tests.cpp
some fixes.
2020-02-14 16:25:25 -08:00
jordan maples b6b1e9c3cf assert -> expect_true 2020-02-14 16:13:21 -08:00
Jordan Maples [MSFT] 67a7f7eaef errors in appveyor are indicating that AsWritableByesCompilersFor needs to be static. 2020-02-14 15:44:58 -08:00
Jordan Maples [MSFT] 41ae38f197 addressing a few more comments and adding gsl-std span compatibility tests 2020-02-14 15:24:46 -08:00
Jordan Maples [MSFT] 926aaeca56 reviewed the pr in its entirety and made some slight modifications. Removed all members and fields marked as deprecated. 2020-02-11 16:36:07 -08:00
Jordan Maples [MSFT] cce6ee563e address issue with v140 toolset 2020-02-10 17:09:58 -08:00
Jordan Maples [MSFT] dd78144c2e msvc and gcc work locally 2020-02-10 13:17:22 -08:00
Hannes Steffenhagen 849f14083a Add a note on CMake usage of exported target to the README 2020-02-08 13:11:11 +00:00
Hannes Steffenhagen 9c0c6b246c Add Microsoft.GSL::GSL alias for GSL
This ensures that dependents can be agnostic about
whether GSL was added via `add_subdirectory` or `find_package`
2020-02-08 12:58:25 +00:00
Hannes Steffenhagen 886fc95142 Remove PUBLIC_HEADER attribute from install command
Since we already explicitly install `include/gsl`, this
doesn’t do anything.
2020-02-08 12:55:19 +00:00
Hannes Steffenhagen ebe8844344 Make GSL includes based on CMAKE_INSTALL_INCLUDEDIR
This is to avoid inconsistencies with the `install`
command which specifies this as the destination for includes.
2020-02-08 12:53:40 +00:00
Jordan Maples [MSFT] d8fa68c4a5 address build failures 2020-02-07 14:40:09 -08:00
Jordan Maples [MSFT] b81d6e40e1 constexpr the make_subspan calls. 2020-02-07 14:15:44 -08:00
Jordan Maples [MSFT] 377b2db537 almost parity with std::span 2020-02-07 14:09:57 -08:00
Jordan Maples [MSFT] 202f332702 Merge pull request #845 from cbuchart/master
Fix incorrect package name for vcpkg
2020-02-07 10:41:33 -08:00
cbuchart 3f0d733466 Fix incorrect package name for vcpkg 2020-02-07 15:25:58 +01:00
Jordan Maples [MSFT] a49ff1b8df update span specialization of at, change some tests back to int i with narrowing for the comparisons. 2020-02-05 17:12:31 -08:00
Jordan Maples [MSFT] 3b9d15f49f reverting changes to gsl::index 2020-02-05 17:02:23 -08:00
Jordan Maples [MSFT] 45f016d96f add back capture variable for comparison in span_test 2020-02-05 14:41:41 -08:00
Jordan Maples [MSFT] ff5f7973a2 remove brackets around this deref for span_iterator operators 2020-02-05 14:36:34 -08:00
Jordan Maples [MSFT] 7fcc142ffc addressing travis errors 2020-02-05 14:32:08 -08:00
Jordan Maples [MSFT] 432be4852c captureing result of iterator comparisons to address -Wunused-comparison 2020-02-05 13:59:48 -08:00
Jordan Maples [MSFT] 5cf1610cfe prevent overflow in size_bytes. fix compilation issue for clang 3.6 and 3.7 2020-02-05 12:58:49 -08:00
Jordan Maples [MSFT] d7e1611137 gsl::index ptrdiff_t -> size_t. remove span::at span::operator(). 2020-02-04 16:53:43 -08:00
Jordan Maples [MSFT] 5a1e4f3953 update index_type to size_type, fix a couple Expects 2020-02-04 15:31:33 -08:00
Jordan Maples [MSFT] 61c6ef8d42 remove index_type from string_span, update comments 2020-02-04 13:30:03 -08:00
Jordan Maples [MSFT] db2134485a Merge branch 'dev/jomaples/unsigned' of https://github.com/jordanmaples/gsl into dev/jomaples/unsigned 2020-02-04 12:01:30 -08:00
Jordan Maples [MSFT] 0c6ce424ab refactoring index_type to size_type, changing expects 2020-02-04 12:01:27 -08:00
Jordan Maples [MSFT] e9fea77bcb Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 18:31:50 -08:00
Jordan Maples [MSFT] 4ec7058b56 Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 18:31:21 -08:00
Jordan Maples [MSFT] 49e7ed1ebf updating comparisons 2020-02-03 18:27:09 -08:00
Jordan Maples [MSFT] 592c28c6d1 fixing spaces in gsl_suppress 2020-02-03 18:18:14 -08:00
Jordan Maples [MSFT] 877816faa4 addressing feedback 2020-02-03 18:16:41 -08:00
Jordan Maples [MSFT] 2b7a8f1f2f Merge branch 'dev/jomaples/unsigned' of https://github.com/jordanmaples/gsl into dev/jomaples/unsigned 2020-02-03 18:14:52 -08:00
Jordan Maples [MSFT] e0dc8095b3 addressing feedback 2020-02-03 18:13:14 -08:00
Jordan Maples [MSFT] 81c2a1da15 addressing feedback 2020-02-03 18:12:57 -08:00
Jordan Maples [MSFT] 827fafd32c Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 18:12:32 -08:00
Jordan Maples [MSFT] 24646c6f7c Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 17:51:45 -08:00
Jordan Maples [MSFT] f4ee6ee73b Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 17:51:25 -08:00
Jordan Maples [MSFT] 1815791af8 Change iterator from Span* & ptrdiff_t to pointer, pointer, pointer 2020-02-03 16:26:36 -08:00
Jordan Maples [MSFT] d9d6ea8196 remove comparison to dynamic_extent 2020-02-03 13:53:38 -08:00
Jordan Maples [MSFT] 3e40b3fa4b Merge branch 'dev/jomaples/unsigned' of https://github.com/jordanmaples/gsl into dev/jomaples/unsigned 2020-02-03 13:52:11 -08:00
Jordan Maples [MSFT] d0fdbdbffa fixing suppress spacing 2020-02-03 13:52:00 -08:00
Jordan Maples [MSFT] a430823b43 Update include/gsl/string_span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 13:47:34 -08:00
Jordan Maples [MSFT] 9bb900e834 Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 13:46:18 -08:00
Jordan Maples [MSFT] 17e372c155 Update include/gsl/span
Co-Authored-By: Casey Carter <cartec69@gmail.com>
2020-02-03 13:45:56 -08:00
Jordan Maples [MSFT] 5b8cf5422b casting -1 for dynamic extent 2020-02-03 12:49:57 -08:00
Jordan Maples [MSFT] eabd9358f0 addressing some comments 2020-02-03 12:46:37 -08:00
Jordan Maples [MSFT] ad71477183 fix build breaks 2020-02-03 12:26:15 -08:00
Jordan Maples [MSFT] c31593dd0d updating from test loop from int to size_t 2020-02-03 11:01:24 -08:00
Jordan Maples [MSFT] 8579165d0a change span from signed to unsigned to align to std 2020-02-03 10:56:31 -08:00
Jordan Maples [MSFT] b4dd39615a Merge pull request #842 from JordanMaples/dev/jomaples/not_null
remove move constructor for not_null.
2020-01-30 19:51:35 -08:00
Jordan Maples [MSFT] 6b23937baf remove move constructor for not_null. 2020-01-30 17:00:13 -08:00
Jordan Maples [MSFT] 6e20bfbba2 Merge pull request #836 from Farwaykorse/suppressionToCMake
Compiler warning suppression for tests to CMake
2020-01-22 11:59:51 -08:00
Jordan Maples [MSFT] 57dd11b20f Merge pull request #840 from NancyLi1013/vcpkg-instructins
Add vcpkg installation instructions
2020-01-22 11:52:47 -08:00
NancyLi1013 c61b1503ad Add vcpkg installation instructions 2020-01-18 23:12:43 -08:00
Jordan Maples [MSFT] 7ba7f87475 Merge pull request #837 from Farwaykorse/fix/disable_exceptions
Restore disabling of exceptions for MSVC in "no exception tests"
2020-01-17 09:13:44 -08:00
Jordan Maples [MSFT] d976d41494 Merge pull request #838 from kunaltyagi/patch-1
Fix spelling error in docs
2020-01-17 09:13:09 -08:00
Kunal Tyagi 26a68c882b Correct spelling error in docs 2020-01-17 14:32:37 +09:00
Roelf-Jilling 95730a80c4 Restore disabling of exceptions for Microsoft STL in "no exception tests" 2020-01-16 19:31:31 +01:00
Roelf-Jilling 72312b6474 Revert "adding /EHsc for msvc cmake target gsl_test_config_noexcept"
This reverts commit 3539bd8008.
2020-01-16 19:29:36 +01:00
Roelf-Jilling adc5fb0d14 TravisCI: use more bash variable checks
To detect typos and logic errors.
2020-01-16 17:55:58 +01:00
Roelf-Jilling b29a18d3a8 TravisCI: use stages to end run when newest compilers fail
These tend to have the best error messages.
2020-01-16 17:55:58 +01:00
Roelf-Jilling 5082a21b04 TravisCI: keep googletest directories between CMake generator runs 2020-01-16 17:55:58 +01:00
Roelf-Jilling 8edc449efb CMake 3.2.3 or later to use AppleClang on OSX
GoogleTest uses CMake compile feature detection.
2020-01-16 17:55:58 +01:00
Roelf-Jilling 5caf336e02 TravisCI: validate CMake configuration with all supported releases 2020-01-16 17:55:58 +01:00
Roelf-Jilling ecff9e623c TravisCI: performance - use the default CMake version on CI images 2020-01-16 17:55:58 +01:00
Roelf-Jilling f828c55ec7 TravisCI: add Clang-8 and 9 2020-01-16 17:55:58 +01:00
Roelf-Jilling 586c4e52f8 TravisCI: add GCC-8 and 9 2020-01-16 17:55:58 +01:00
Roelf-Jilling e1a37d0430 Suppress -Wundefined-func-template for C++17 Clang v5.0.x and AppleClang 9.1
Warning appears on v5.0.2 from apt.llvm.org and Ubuntu provided v5.0.1
2020-01-16 17:55:58 +01:00
Roelf-Jilling f0061bfa2a TravisCI: default to Ubuntu Bionic and use Xenial where needed 2020-01-16 17:55:58 +01:00
Roelf-Jilling 8655dc1583 TravisCI: Xcode 9.0 earliest with C++17 support 2020-01-16 17:55:56 +01:00
Roelf-Jilling d768179ff6 TravisCI: add XCode v9.4, 10.1, 10.3 and 11.3 2020-01-16 17:54:59 +01:00
Roelf-Jilling 81f56796a1 MSVC and CoreChecker warning suppression for tests to CMake
Suppress CppCoreCheck warnings on GTest macros.
Suppress CppCoreCheck advice to use the GSL
2020-01-16 11:49:15 +01:00
Roelf-Jilling 4cbd894812 Enable more warnings in GCC 2020-01-16 11:49:15 +01:00
Roelf-Jilling d08ff53e61 Use [[maybe_unused]] with C++17 2020-01-16 11:49:15 +01:00
Roelf-Jilling 186f5d21c1 Move compiler warning suppression for tests from cpp files to CMake 2020-01-16 11:49:00 +01:00
Roelf-Jilling cdedae897c TravisCI: remove redundant setting of CXX variable 2020-01-15 21:06:14 +01:00
Jordan Maples [MSFT] 888b9b9723 Merge pull request #830 from JordanMaples/dev/jomaples/add_missing_span_functions
Add span::front and span::back. See #828.
2020-01-10 10:20:47 -08:00
Jordan Maples [MSFT] 395a5bf550 Merge branch 'master' into dev/jomaples/add_missing_span_functions 2020-01-10 10:20:37 -08:00
Jordan Maples [MSFT] 96b6964b30 Merge pull request #829 from JordanMaples/dev/jomaples/deprecate_span_non_std_functions
Deprecate span::at & span::operator(). See #828.
2020-01-10 10:19:32 -08:00
Jordan Maples [MSFT] a1e6fcbc46 Merge branch 'master' into dev/jomaples/deprecate_span_non_std_functions 2020-01-09 16:39:24 -08:00
Jordan Maples [MSFT] 2d878b94ee Merge branch 'master' into dev/jomaples/add_missing_span_functions 2020-01-09 16:37:12 -08:00
Jordan Maples [MSFT] b076205338 Merge branch 'dev/jomaples/deprecate_span_non_std_functions' of https://github.com/JordanMaples/GSL into dev/jomaples/deprecate_span_non_std_functions 2020-01-09 14:40:08 -08:00
Jordan Maples [MSFT] 75936c3109 missed from the merge 2020-01-09 12:56:00 -08:00
Jordan Maples [MSFT] cfd82aef4e deprecating span::at and span::operator() 2020-01-09 12:51:28 -08:00
Jordan Maples [MSFT] 3c0b38b777 Merge pull request #833 from JordanMaples/dev/jomaples/noexceptspan
Update noexcept in span and span_iterator
2020-01-09 12:45:17 -08:00
Jordan Maples [MSFT] 2bc6a7cb12 Merge pull request #825 from omartijn/free_standing_begin_end_ssize
Implement free-standing (c|r|cr)(begin|end) and ssize functions
2020-01-09 12:32:31 -08:00
Jordan Maples [MSFT] c7f9b3301a noexcepting new functions 2020-01-09 12:13:12 -08:00
Jordan Maples [MSFT] 6eccc81c5f Merge branch 'dev/jomaples/add_missing_span_functions' of https://github.com/JordanMaples/GSL into dev/jomaples/add_missing_span_functions 2020-01-09 12:09:24 -08:00
Jordan Maples [MSFT] 4b823b1651 adding front and back 2020-01-09 12:03:27 -08:00
Jordan Maples [MSFT] 3bf4106a44 noexcept all of the span iterator stuff 2020-01-08 12:34:11 -08:00
Martijn Otto fa8a8117a0 Add tests for free-standing iterator and size functions 2020-01-08 21:02:02 +01:00
Martijn Otto b186b6cc68 Implement free-standing (c|r|cr)(begin|end) and ssize functions 2020-01-08 21:01:52 +01:00
Jordan Maples [MSFT] b33bd4aebe updating all span functions to be noexcept 2020-01-08 11:51:15 -08:00
Jordan Maples [MSFT] 0fefba89da Merge pull request #832 from JordanMaples/dev/jomaples/buildfix
fix appveyor build issues.
2020-01-08 11:47:22 -08:00
Jordan Maples [MSFT] f04907c2f6 added suppression for missing destructor override 2020-01-08 10:13:00 -08:00
Jordan Maples [MSFT] 7786da91c9 Merge pull request #831 from JordanMaples/dev/jomaples/gtest
Migrate from Catch to GoogleTest & always terminate on contract violation
2020-01-07 15:41:25 -08:00
Jordan Maples [MSFT] 40bc3c3f00 testing something 2019-12-20 13:32:14 -08:00
Jordan Maples [MSFT] 8577033f13 addressing comments 2019-12-19 14:05:02 -08:00
Jordan Maples [MSFT] 3539bd8008 adding /EHsc for msvc cmake target gsl_test_config_noexcept 2019-12-13 13:56:42 -08:00
Jordan Maples [MSFT] 17ad4495fb deprecate gsl::details::throw_exception. remove unused header in gsl_assert. gsl_util to use terminate instead of throw_exception 2019-12-13 13:40:25 -08:00
Jordan Maples [MSFT] 6c5c708877 change from string to char* 2019-12-12 16:48:59 -08:00
Jordan Maples [MSFT] 0931262acf appveyor failed to start, sending dummy commit 2019-12-12 14:39:12 -08:00
Jordan Maples [MSFT] 5099e8fa3e removed string_view for string in tests 2019-12-12 11:15:41 -08:00
Jordan Maples [MSFT] 4f6f05d463 changing text in notices & readme. adding terminate handler for tests 2019-12-12 10:55:26 -08:00
Jordan Maples [MSFT] ec05ecd6b1 dummy commit to trigger appveyor 2019-12-10 11:58:42 -08:00
Jordan Maples [MSFT] 0784866608 added back death test, fixed VS2019 test failures 2019-12-09 16:08:27 -08:00
Jordan Maples 9a88262544 fixing suppression of gtest warnings for gcc 2019-12-06 16:03:47 -08:00
Jordan Maples [MSFT] b39a9732f8 attempting to fix the gtest print issues in vs17 2019-12-04 13:46:50 -08:00
Jordan Maples [MSFT] 87eaa45445 suppressing -Wundef in clang (GTest emitted) 2019-12-04 12:48:13 -08:00
Jordan Maples [MSFT] 43aca2646b ignore warnings from gtest 2019-12-04 12:30:58 -08:00
Jordan Maples [MSFT] 603b4671c1 removing unused function 2019-12-03 15:24:52 -08:00
Jordan Maples [MSFT] 2b10729386 gtest migration 2019-12-03 14:32:25 -08:00
Jordan Maples [MSFT] 7004ef506c adding front and back 2019-11-19 16:03:55 -08:00
Jordan Maples [MSFT] 5e0d76a1a7 deprecating span::at and span::operator() 2019-11-19 14:31:21 -08:00
Jordan Maples [MSFT] 7e99e76c97 Merge pull request #826 from JordanMaples/dev/jomaples/ctad_fix_v2
fix ctad warning in llvm
2019-11-18 13:02:53 -08:00
Jordan Maples [MSFT] 263440f2a1 changing white-space in comment to get tests to rerun 2019-11-18 11:39:36 -08:00
Jordan Maples [MSFT] a7759e6d3f lower __cpp_deduction_guide version number from 201907 to 201611 2019-11-18 10:14:05 -08:00
Jordan Maples [MSFT] 128b4356ac changing check from __cplusplus 201703L to __cpp_deduction_guides 201907L 2019-11-15 16:29:41 -08:00
Jordan Maples [MSFT] 8e481ebe19 adding deduction guide for strict_not_null 2019-11-15 14:41:38 -08:00
Jordan Maples [MSFT] 4610f26b33 forgot comment 2019-11-15 12:43:33 -08:00
Jordan Maples [MSFT] d0e5daf441 fix ctad warning in llvm 2019-11-15 12:11:44 -08:00
Cristian Morales Vega b213c89700 Add missing #include if built with GSL_USE_STD_BYTE=1
cstddef was being included to detect whether GSL_USE_STD_BYTE should be
set to 0 or 1. But if the user provided GSL_USE_STD_BYTE no detection is
required and the header was never included.
2019-11-08 16:37:23 +00:00
Jordan Maples [MSFT] 9939d5889b Merge pull request #822 from JordanMaples/dev/jomaples/lib-byte-check
gsl_byte to inspect __cpp_lib_byte
2019-10-25 11:42:01 -07:00
Jordan Maples 22cba52114 update comments 2019-10-25 10:12:41 -07:00
Jordan Maples 97dc8f83fc adding check to __cpp_lib_byte, which was added to the defn for 15.8 2019-10-24 17:07:42 -07:00
Jordan Maples [MSFT] 71ec9f84d8 Merge pull request #2 from microsoft/master
updating personal branch.
2019-10-23 11:50:25 -07:00
Jordan Maples [MSFT] 3d56ba9e7f Merge pull request #813 from JordanMaples/dev/jomaples/deprecate_multispan
Deprecate multi_span, strided_span, etc
2019-10-09 15:11:59 -07:00
Jordan Maples [MSFT] cf9cc34da8 Merge pull request #815 from matt77hias/patch-1
Added std::exchange (C++14) to make the intent more explicit
2019-10-09 15:05:26 -07:00
Matthias Moulin 0a78d8ea3c Added std::exchange (C++14) to make the intent more explicit 2019-10-07 21:49:50 +02:00
Jordan Maples [MSFT] 02d1051fdd Merge pull request #814 from sizmailov/fix_typos
Fix typos in gsl/pointers
2019-10-06 14:39:57 -07:00
Sergei Izmailov 275e0176c0 Fix typos in gsl/pointers 2019-10-06 19:20:15 +03:00
Jordan Maples 4b289d4cf0 lack of nl for bounds_test 2019-10-04 14:15:24 -07:00
Jordan Maples 6ff4a5287d accidentally commented out pragma 2019-10-04 14:13:54 -07:00
Jordan Maples 2b8f7aea32 adding clang/gcc suppression of the deprecation warnings. 2019-10-04 12:38:55 -07:00
Jordan Maples 7adf7eb6fe new messages 2019-10-03 17:52:49 -07:00
Jordan Maples 5e4463a7c1 removing function deprecation, adding additional class / struct deprecations 2019-10-03 15:47:25 -07:00
Jordan Maples [MSFT] 10ce5b634f Merge pull request #812 from JordanMaples/dev/jomaples/typo_fixes
Fixing typo "Guideline" as "Guidelines"
2019-10-03 09:37:41 -07:00
Jordan Maples eb995b3671 deprecating strided_span 2019-10-02 16:17:46 -07:00
Jordan Maples b630dfe36a Guideline -> Guidelines
fixing issue as reported in issue #746
2019-10-02 15:42:40 -07:00
Jordan Maples e026971c03 deprecation, removing cassert 2019-10-02 15:40:15 -07:00
Jordan Maples bbeb0bdc91 initial deprecation of multi_span and strided_span 2019-09-28 12:54:18 -07:00
Jordan Maples [MSFT] 23066c829f Update README.md 2019-09-04 15:10:14 -07:00
Jordan Maples [MSFT] a454d295ed Merge pull request #803 from B1Z0N/master
Fixed memory leaks and out of bound access
2019-09-04 14:04:47 -07:00
B1Z0N ba9af38494 Merge branch 'master' of https://github.com/B1Z0N/GSL 2019-09-01 00:38:10 +03:00
B1Z0N d5382a293b Fixed memory leaks 2019-09-01 00:36:13 +03:00
B1Z0N 787e7ef616 Thanks to @stayprivates fixed out of bounds access in "TestNotNullostream" 2019-09-01 00:35:04 +03:00
Jordan Maples [MSFT] 1046c9d247 Merge pull request #1 from microsoft/master
updating from root
2019-08-30 12:37:36 -07:00
Jordan Maples [MSFT] b576cc6ce3 Merge pull request #769 from jack17529/patch-1
Update usage of difference_type in span
2019-08-15 14:49:12 -07:00
Jordan Maples [MSFT] 2ce3177ebd Merge pull request #800 from eyalroz/master
Fixes #798 : Dropping inclusion of `gsl/pointers` in `string_span`
2019-08-15 14:42:07 -07:00
Johel Ernesto Guerrero Peña cee1929de7 Fix GNUC typo (#780)
Resolves #779
2019-08-14 12:56:53 -07:00
beinhaerter 1d48188de9 Fixed check if std::byte is available (#764)
The check for std::byte existance fails on gcc 8.2. According to https://en.cppreference.com/w/cpp/utility/feature_test it is necessary to `#include <cstddef>` before checking `__cpp_lib_byte`.
2019-08-14 12:40:35 -07:00
Eyal Rozenberg b05a4464b9 Fixes #798 : Dropped inclusion of gsl/pointers in string_span. 2019-08-05 13:16:42 +03:00
NN 1212beae77 Add Visual Studio 2019 image for tests (#787)
* Add Visual Studio 2019 image for tests

Refer to https://github.com/appveyor/ci/issues/2907
VS2019 is enabled per request.

* Use CMake 3.14

* Fix CMake output directory

* trigger build

* Trigger build
2019-06-12 21:27:49 -07:00
Ian Taylor 66809c6852 make TypeListIndexer constexpr (#733) 2019-06-06 14:16:08 -07:00
Hannes Steffenhagen 0551cad467 Merge branch 'master' into hunterization 2019-05-09 18:09:21 +01:00
Fei Sun b74b286d5e add value_type size_type for string_span (#727) 2019-04-11 10:40:02 -07:00
JACK_1729 2a1ef25406 Update span
About my Issue - https://github.com/Microsoft/GSL/issues/765
2019-02-20 20:25:50 +05:30
Anna Gringauze 7d78b743e4 added clang7.0 to Travis configuration and README (#763) 2019-01-16 19:58:38 -08:00
Anna Gringauze 6418b5f4de Clang cl (#762)
* Added c++17 test configurations for clang5.0 and clang6.0

* Fix #739 correct cppcorecheck warnings for clang-cl

* Add clang-cl  configurations

* Corrections Appveyor;
Temporarily disable msvc compilation for faster testing (#741)

* Add path to clang-cl.exe (#741)

* Escape backslash in path (#741)

* Update vcpkg (#741)

* Check vcpkg version; try without building vcpkg; use latest clang-cl from path (#741)

* Fix blocks in ps script (#741)

* Try accessing APPVEYOR_BUILD_FOLDER variable (#471)

* Update span size() bug confirmation test for GCC 6.5 (#741)

* MSVC flags to Clang-cl; disable c++98-compat and undefined macro warnings (#741)

* Suppress clang warning on tests (missing-prototypes) (#741)

* Fix clang warning -Wnewline-eof (#741)

* Fix clang warning -Wdouble-promotion (#741)

* Set linker explicitly

* Clean condition statement

* For Clang, fallback to the AppVeyor installed version of CMake

* Fix clang warning -Wmissing-variable-declarations

* Fallback to the MSVC linker until vcpkg has been updated

* Revert "Fallback to the MSVC linker until vcpkg has been updated"

This reverts commit 7263f3289e.

* Fix clang warning -Wunused-member-function

* Fix clang warning -Wmissing-noreturn

* Fix clang warning -Winvalid-noreturn on Windows

* Add macro block end comment on large #if blocks

* Workaround: fallback to mscv link.exe

* Workaround: get msvc paths into PowerShell through intermediate file

* Workaround: fix, remove "PATH=" from text

* Workaround: try with full-path; and return user PATH

* Workaround: fix, escape backslashes

* Revert all since "Workaround: fallback to mscv link.exe" did not work on AppVeyor

This reverts the commits:
bda3d6a428
97062933ac
0f4fb04bac
1b0c19afd1
a5739ea5f0

* Suppress output of git pull; remove vcpkg from cache

* Re-enable AppVeyor builds for all platforms

* Correct typo

Co-Authored-By: Farwaykorse <Farwaykorse@users.noreply.github.com>

* Add Clang-cl 7.0.0 to the supported platforms

* Revert "Fix clang warning -Wunused-member-function"

This reverts commit 6fe1a42035.

* Fix or locally suppress clang warning -Wunused-member-function

* format touched code and correct comment

* git pull --quiet

* fix logic error in workaround

* fix missing bracket

* Suppress output of mkdir

* Replace MSBuild with Ninja

* Suppress output of 7z

* Add architecture flags for Clang

* Drop workaround for lld-link

* 7-zip Overwrite and Alternative output suppression without suppressing errors

Replaces 3c1c0794dd

* AppVeyor setup and CMake before build

* reorder compiler configuration

* remove unnecessary

* remove -fno-strict-aliasing

* remove -Wsign-conversion, since before v4.0 part of -Wconversion

* -Wctor-dtor-privacy is GCC only

* remove -Woverloaded-virtual part of -Wmost, part of -Wall

* add -Wmissing-noreturn

* remove the pragmas for -Wunused-member-function

* Re-add MSBuild generator on AppVeyor

* Print CMake commands

* Add MSBuild toolset selection

* Separate Architecture setting

* clang-cl: add -Weverything

* clang-cl -Wno-c++98-compat

* clang-cl -Wno-c++98-compat-pedantic

* clang-cl -Wno-missing-prototypes

* clang-cl C++14 -Wno-unused-member-function

* clang-cl -Wundef __GNUC__

* clang++: add -Weverything

* clang++ -Wno-c++98-compat

* clang++ -Wno-c++98-compat-pedantic

* clang++ -Wno-missing-prototypes

* clang++ -Wno-weak-vtables

* clang++ C++14 -Wno-unused-member-function

* clang++ fix -Wundef _MSC_VER

* clang++ -Wno-padded

* clang++ solve -Wdeprecated

* Add AppleClang compiler target
Since CMake v3.0 use of Clang for both is deprecated

* clang++ v5.0 C++17 -Wno-undefined-func-template

* Add VS2015 + LLVM/clang-cl to AppVeyor

* Do not disable constexpr when compiling with clang-cl on Windows

* Clean-up clang-only warnings (now under -Weverything)

* Revert "Fix clang warning -Winvalid-noreturn on Windows"

This reverts commit 2238c4760e.

* Suppress -Winvalid-noreturn for the MS STL noexception workaround

* CMake: put preprocessor definition in target_compile_definitions

* Solve compiler warning C4668: __GNUC__ not defined
2019-01-15 10:27:34 -08:00
Johel Ernesto Guerrero Peña 6eeed739f1 Make narrow constexpr (#698) 2019-01-14 18:37:37 -08:00
Anna Gringauze 9ff6e19ea9 Dev/annagrin/remove explicit not null constructor (#743)
* Added c++17 test configurations for clang5.0 and clang6.0

* Removed explicit not_null constructor, sloppy_not_null, added strict_not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests

* Removed explicit not_null constructor, sloppy_not_null, added strict_not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests

* fixed build break for gcc7

* added more tests

* added more non-compiling tests

* Addressed PR comments and suppressed a code analysis warning

* Fixed test failure in not_null tests
2019-01-14 16:45:47 -08:00
Alex Green 7a7d025ffa Make CheckRange constexpr (#754) (#755) 2019-01-14 16:44:45 -08:00
k-brac be3c3c2731 Fixes CMAKE_VERSION check (#759)
* Fixes CMAKE_VERSION check

Fixes #758 by using the correct comparison operator for a version
See documentation at https://cmake.org/cmake/help/latest/command/if.html
Thanks to this change, gsl natvis is properly included in a visual studio solution

* cmake version check for cmake < 3.7
2019-01-14 16:43:17 -08:00
hannesweisbach 0f68d133fa Suppress Warnings in GSL Headers (#731)
Suppress warnings in GSL headers using the SYSTEM keyword for target_include_directories(). This enables developers to see warnings standalone builds but hides them from users in non-standalone builds.
2018-11-28 15:37:59 -08:00
beinhaerter 88aca1caf3 added noexcept to get rid off VC warning con.4 (#748) 2018-11-28 11:57:43 -08:00
Stefan Dinkelacker 2e4d0d7e22 Fix spelling of library name (#747) 2018-11-28 11:53:38 -08:00
kile0 5a7093f983 Use the c++17 constexpr if in CheckRange if possible (#753)
* change c++17 to use constexpr if in CheckRange

* remove unnecessary macro

* use the portable feature test macro rather than direct version check
2018-11-28 11:52:11 -08:00
Anna Gringauze b673375719 Dev/annagrin/fix span size test gcc (#750)
* Added c++17 test configurations for clang5.0 and clang6.0

* fixed test for broken span.size() in gcc6.5
2018-11-27 17:28:57 -08:00
Dave Hill c02ddae4bc Span can be constructed from empty std::array safely (#686)
* Span std::array c'tor uses arr.data() instead of &arr[0]
- Fixes runtime issues when constructing from an empty std::array

* Construct span with std::data if C++17 detected

* Specialize span c'tor for std::array of length 0, set storage to nullptr
2018-11-05 15:39:41 -08:00
Ian Taylor 2bf9f137a6 make BoundsRanges constexpr (#732)
* make BoundsRanges constexpr

* fix clang compilation error

* fix windows compilation
2018-11-05 15:26:27 -08:00
Stefan Reinhold 457fb25609 Merge branch 'hunterization' of github.com:ithron/GSL into hunterization 2018-09-07 17:27:54 +02:00
Stefan Reinhold 8428e083e4 Merge branch 'master' into hunterization 2018-09-07 17:27:31 +02:00
Anna Gringauze 1995e86d1a span constructor no address (#723)
* Changed &arr[0] to std::array<T, N>::data and std::address_of to protect against overloaded operator&.

* Removed the usage of `std::addressof` because it is a C++ 17 feature. Using decay for C arrays instead.

* Add unit tests for #662.

* Added c++17 test configurations for clang5.0 and clang6.0

* fixed CppCoreCheck pointer decay warning
2018-08-19 17:10:53 -07:00
Anna Gringauze 585f48ce55 better check for branch opt (#724)
* Added c++17 test configurations for clang5.0 and clang6.0

* Simplified optimization in span::operator[]
2018-08-19 16:27:30 -07:00
Stephan Dollberg 86be2366c7 Fix #717 - Add empty() to strided_span (#718) 2018-08-17 11:47:03 -07:00
Anna Gringauze 55aad0ab6d Dev/annagrin/explicit notnull transition description (#722)
* Added c++17 test configurations for clang5.0 and clang6.0

* Improved description how to make transition to explicit not_null constructor
2018-08-17 11:36:26 -07:00
Anna Gringauze 5016ce4a4d Dev/annagrin/opt neg branch (#721)
* Added c++17 test configurations for clang5.0 and clang6.0

* Added optimization that removes a branch from span::operator[]

* minor beauty fix

* added a better message for the optimization, fixed signed/unsigned warning

* better check fir wrap-around possibility
2018-08-17 11:36:06 -07:00
Anna Gringauze 6241b3faa6 Dev/annagrin/sloppy not null (#712)
* Added c++17 test configurations for clang5.0 and clang6.0

* added transition helper sloppy_not_null

* Moved gsl_transition to a samples folder

* Fixed build break and static analysis warnings
2018-08-13 09:55:48 -07:00
Anna Gringauze 831584d947 Dev/annagrin/make not null (#711)
* Added c++17 test configurations for clang5.0 and clang6.0

* Added make_not_null helper to create a not_null

Introduction of explicit not_null constructor made it cumbersome to create not_nulls
in c++14. Adding make_not_null helper. Usage (see tests):

int i = 42;

auto x = make_not_null(&i);
helper(make_not_null(&i));
helper_const(make_not_null(&i));

* Added std::forward to make_not_null, fixed some code analysis warnings

* Fix build break in VS2015 Release configuration

* Fix build break in VS2015 Release configuration
2018-08-13 02:22:02 -07:00
Anna Gringauze f1a2e91e4e fixed typo 2018-08-12 21:45:39 -07:00
Anna Gringauze cea0d0ac2b fix cppcorecheck warnings (#703)
* Added c++17 test configurations for clang5.0 and clang6.0

* Fixed CppCoreCheck warnings in GSL and tests

- Added CMakeSettings.json for VS Open Folder configuration
	- So we can easily run CppCoreCheck in VS
- Fixed CppCorecheck warnings where it made sense
- Suppressed the rest
	- Some suppression does not work due to compiler/tool bugs,
          so replaced by #pragma disable
	- CppCoreCheck has noise, suppressed those with comments
	- Catch produces many warnings, blanket-supressed them all
- Had to fix clang formatting to keep attributes in place
	- clang-format does not support attributes, so I am using
        - "CommentPragmas: '^ NO-FORMAT:'" to skip formatiting on them
- Removed GSL_NOEXCEPT macro, removed incorred noexcepts

* Ignore unknown attributes

* ignore unknown attributes in noexception mode tests

* fixed C26472 in at()

* created GSL_SUPPRESS macro to allow all compilers to parse suppression attributes

* try to fix gcc compilation problems with attributes

* ignore gsl::suppress for gcc

* move suppression to function level on return statements

clang5.0 and up does not allow attributes on return statemets in constexpr functions

* move suppression to function level on return statements

* use GSL_SUPPRESS in algorithm_tests

* Addressed PR comments
2018-08-12 21:44:17 -07:00
Anna Gringauze 6a75903c79 replace uses of GSL_NOEXCEPT macro (#719)
* Added c++17 test configurations for clang5.0 and clang6.0

* removed GSL_NOEXCEPT

- Removed GSL_NOEXCEPT macro
- Replaced by noexcept keyword when needed
- removed noexcept where a function could throw

* remove unneded undef

* fixed replace errors

* removed noexcept where function can throw
2018-08-12 20:19:16 -07:00
Stefan Reinhold b6c531f7c1 Explicitly check for availability of std::byte (fixes #713) (#714)
* Explicitly check for availbility of std::byte

GCC > 7.3 defines __cpp_lib_byte >= 201603 when std::byte is available.
On libc++ std::byte is available since version 5.0. This can be checked
with _LIBCPP_VERSION >= 5000.
This fixes 713.

* Add missing \ in preprocessor check
2018-08-03 10:39:12 -07:00
Stefan Reinhold 73022d1103 Merge branch 'master' into hunterization 2018-08-03 00:53:40 +02:00
beinhaerter f4a715816c Suppress warnings on VS (#642)
- gsl::narrow, gsl::narrow_cast and gsl::at are the safe variants suggested by CppCoreGuideline. It does not make sense to let VS warn inside the implementation of these functions that unsafe static_cast is used and that the safe variants shall be used.
- Suppress warning that throw_exception can be declared noexcept (for the GSL_TERMINATE_ON_CONTRACT_VIOLATION case)
2018-07-31 17:53:00 -07:00
Anna Gringauze 1f76fbd168 Dev/annagrin/failfast in noexcept mode windows (#710)
made terminate call __fastfail in noexcept mode when using msvc
2018-07-31 17:30:43 -07:00
Stefan Reinhold ffe8ffb452 Dummy commit to force CI re-run 2018-07-18 09:35:36 +02:00
Stefan Reinhold e3ffe1c5cb Fix naming of exported CMake configuration file 2018-07-17 17:56:11 +02:00
Stefan Reinhold e2b57d16f9 Export target GSL in namespace Microsoft.GSL
This is to avoid conflicts with GNU Scientific Library which also has an
exported target named GSL.
2018-07-17 17:43:54 +02:00
Stefan Reinhold 9e1645b990 Do not install .natvis files.
This fixes an issue where CMake complains about INTERFACE_SOURCES
containing a path which is prefixed in source directory on windows.
2018-07-17 13:07:27 +02:00
Stefan Reinhold 0a31a14d09 Fix INSTALL_INTERFACE for exported target
CMake war reporting: 'Target "GSL" INTERFACE_SOURCES property contains
path: "..." which is prefixed in the source directory'.
CMake was confused because the $<BUILD_INTERFACE: ...> had linebreaks
in it.
Putting everything in one line fixed the issue.
2018-07-17 11:56:38 +02:00
Stefan Reinhold 030454e3e9 Fix for Windows: CMake complains about INTERFACE_SOURCES directory 2018-07-17 11:09:58 +02:00
Stefan Reinhold d452c3b061 Make library importable by CMake using find_package 2018-07-17 10:23:44 +02:00
Daniel599 5778149583 Test broken size (#704)
* added test for size check (#590)

* added #if for gcc 6.4 bug (#590)

* hopefully fix #if for gcc 6.4 bug (#590)

* fixed CHECK usage (#590)

* gcc broken size bug is only when using optimizations
2018-07-13 17:19:09 -07:00
Anna Gringauze 0cebbd77bf Added c++17 test configurations for clang5.0 and clang6.0 (#697) 2018-06-15 11:42:16 -07:00
Anna Gringauze 21cb6bb8b0 Added testing for c++17 to latest compilers with test with (#692)
* Added testing with std=c++17 for latest compilers

Added running latest compilers with -std=c++17 option to CI the test matrix,
Updated cmake configuration to allow passing c++ standard on the command line.

* attempt to fix appveyor break

* added clang6.0, removed c++17 tests for clang 5.0

* commented out tests for clang with c++17 die to issue #695

* Addresed comments
2018-06-15 10:13:11 -07:00
Matthieu Poullet a9ef39f14a Fix GCC8 warnings 'useless cast to type'. (#691) 2018-06-15 10:12:37 -07:00
menete ffdaf0fb21 fix gcc build (gcc 7) (#690)
simple solution, disable the specific warning
2018-06-08 11:41:06 -07:00
Anna Gringauze cb2d1af89a Added template argument deduction for not_null (#689)
* Added template  argument deduction for not_null

This allows compilers with c++17 support to infer template
instantiation types when calling not_null constructor:

    int foo(not_null<const int*> x);

    int main()
    {
        int t = 0;
        not_null x{ &t };
        return foo(not_null{ &t });
    }

* replaced deduction guides by a simple constructor

* Updated tests

* fixed check for availability of std::byte

* testing c++1z on clang

* fixed cmakelists extra endif

* include cstddef header for clang and gcc in pointers

* fixed a typo

* fix missing nullptr_t type

* fixed typo in CMakeLists.tst

* change approach to c++17 testing, step one: revert cmake testing, update clang5.0 package

removed using latest c++ due to clang5.0 failing,
update clang5.0 travis config to use llvm-toolchain-trusty-5.0

* addressed comments
2018-06-07 13:36:56 -07:00
beinhaerter 75ad0c1b40 Add as_bytes for basic_string_span, fixes issue #655 (#683) 2018-05-28 19:03:10 -07:00
Anna Gringauze 51ae678d08 Add usage for check-and-unwrap of MS STL iterators (#687)
* Add usage for check-and-unwrap of MS STL iterators

This is Billy ONeal's PR #682 with a typo fixed.

See corresponding change here:
https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/msvc/commit/ca77129308c775f422ecef0c01ad460f75c462ad
That change officially exposes the STL's range checking machinery,
available in MSVC++ "15.8"+
This change augments GSL span::iterator to call into that newly exposed
machinery.

_Verify_range(cit, cit)
Requests that the iterator type check that the parameters form a valid
[First, Last) range iterator pair. This replaces _DEBUG_RANGE and
supporting machinery. The standard library provides a version for
pointers under _IDL != 0; otherwise they are normally provided via
hidden friend functions. Note that declaring some of these hidden
friends for "wrapper" iterators like move_iterator and reverse_iterator
triggers VSO#610735.

cit._Verify_offset(difference_type _Off)
For random-access iterators, performs any asserts that would be
performed by i += _Off; except with possibly a better error message and
without moving the iterator.

cit._Unwrapped()
Returns an "unchecked" or "unwrapped" iterator which has previously been
validated. The iterator may have been validated by a call to
_Verify_range or _Verify_offset (above), or by seeking a checked
iterator to a "high water mark" point.

it._Seek_to(cit) / it._Seek_to(return value from _Unwrapped())
Moves the position of the checked iterator it to the position of the
unchecked iterator supplied. Generally not intended to perform range
checks.

* Fixed build break in VS2015

* fixed constexpr build break when using VS2015
2018-05-22 18:07:49 -07:00
Gabriel Dos Reis 2be3b00faf Merge pull request #678 from sizmailov/sizmailov-patch-1
Update .travis.yml
2018-05-21 10:19:25 -07:00
Casey Carter d6a2242d97 [span] Tell MSVC how to avoid range-checking (#664)
* [span] implement non-member + as a hidden friend

Drive-by: remove garbage `operator-(difference_type, span_iterator)`.

* [span] Use pointers for range-based-for on MSVC
2018-05-09 14:01:22 -07:00
Sergei Izmailov cee3125af7 Update .travis.yml
Fix a typo `clang40` -> `clang50` (#677)
2018-05-07 01:18:08 +03:00
Anna Gringauze 5cbde3008a make terminate_handler __cdecl (#673) 2018-05-02 16:19:37 -07:00
Stephan Dollberg d6b26b367b Add __may_alias__ attribute to gsl::byte (#668)
C++17 defines `std::byte*` to have the same aliasing properties as
`char*`. Hence, we mark it with the `__may_alias__` attribute under gcc
and clang.

Based on the fix by Martin Moene in byte-lite.

Fixes #663
2018-05-01 12:32:31 -07:00
Michal Kaptur c4c1f6395a Cmake version updated in README (#669) 2018-05-01 12:00:37 -07:00
Rian Quinn d933e51b8b v2.0 Patch (#641)
Signed-off-by: Rian Quinn <rianquinn@gmail.com>
2018-04-27 12:56:25 -07:00
ericLemanissier 2fc94db3eb not_null constructor is now explicit (#659)
solves #395
2018-04-24 19:11:43 -07:00
beinhaerter fbe867a9c4 Fix clang-tidy warning about wrong comment on closing namespace (#654) 2018-04-24 19:04:24 -07:00
beinhaerter 697eb5533e final_action move assignment operator =delete against C26432 (#660)
This suppresses warning C26432 on VS2017. Fixes issue #653.
2018-04-24 18:35:53 -07:00
Stephan Dollberg 9c5e21045d Make gsl::details::throw_exception not copy exception object (#667)
This fixes the build with clang 7 which introduces a new warning
`-Wreturn-std-move` which warns about needless copies when a move
operation is available (see https://reviews.llvm.org/rL329914).

We take the exception object by uref so we should throw the forwarded
version.
2018-04-24 18:35:12 -07:00
Neil MacIntosh d25969dbdf Updated README to record another platform report.
As per #644.
2018-04-18 21:12:13 -07:00
37 changed files with 7527 additions and 4692 deletions
+14 -1
View File
@@ -5,7 +5,19 @@ IndentWidth: 4
AccessModifierOffset: -4
NamespaceIndentation: Inner
BreakBeforeBraces: Allman
BreakBeforeBraces: Custom
BraceWrapping:
AfterNamespace: true
AfterEnum: true
AfterStruct: true
AfterClass: true
SplitEmptyFunction: false
AfterControlStatement: true
AfterFunction: true
AfterUnion: true
BeforeElse: true
AlwaysBreakTemplateDeclarations: true
BreakConstructorInitializersBeforeComma: true
ConstructorInitializerAllOnOneLineOrOnePerLine: true
@@ -19,3 +31,4 @@ AlignConsecutiveAssignments: false
AlignTrailingComments: true
SpaceAfterCStyleCast: true
CommentPragmas: '^ NO-FORMAT:'
+430 -118
View File
@@ -1,212 +1,519 @@
# Based on https://github.com/ldionne/hana/blob/master/.travis.yml
language: cpp
sudo: false
notifications:
email: false
# Use Linux unless specified otherwise
os: linux
dist: trusty
dist: bionic
cache:
directories:
- ${TRAVIS_BUILD_DIR}/deps
matrix:
stages:
- name: Latest # build jobs to run first and always
- name: Validation # run other jobs
- name: Legacy # build with all other supported compilers
jobs:
include:
##########################################################################
# Clang on OSX
# Travis seems to take longer to start OSX instances,
# so leave this first for the overall build to be faster
# Validate CMake configuration
##########################################################################
# XCode 8.3
- env: COMPILER=clang++ BUILD_TYPE=Debug
- name: CMake 3.1.3 - latest
stage: Validation
env: &CMAKE_VERSION_LIST
- CMAKE_VERSION: '"3.17.0 3.16.5 3.15.7 3.14.7 3.13.5 3.12.4 3.11.4 3.10.3 3.9.6 3.8.2 3.7.2 3.6.3 3.5.2 3.4.3 3.3.2 3.2.3 3.1.3"'
- GSL_CXX_STANDARD: 14
addons: # Get latest release (candidate)
apt:
sources:
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic main'
key_url: 'https://apt.kitware.com/keys/kitware-archive-latest.asc'
- sourceline: 'deb https://apt.kitware.com/ubuntu/ bionic-rc main'
packages:
- cmake
script:
- |
cd ./build
( set -eu
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
export CXX=clang++
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
)
- name: CMake 3.2.3 - 3.17.0
stage: Validation
os: osx
osx_image: xcode11.3
env:
- CMAKE_VERSION: '"3.17.0 3.16.5 3.15.7 3.14.7 3.13.5 3.12.4 3.11.4 3.10.3 3.9.6 3.8.2 3.7.2 3.6.3 3.5.2 3.4.3 3.3.2 3.2.3"'
script:
- |
cd ./build
( set -eu
for CMAKE in ${CMAKE_path[@]}; do test_CMake_generate $CMAKE; done
)
##########################################################################
# AppleClang on OSX
##########################################################################
# Xcode 8.3
- name: AppleClang Xcode-8.3 C++14 Debug
stage: Legacy
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode8.3
compiler: clang
- env: COMPILER=clang++ BUILD_TYPE=Release
- name: AppleClang Xcode-8.3 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode8.3
compiler: clang
# XCode 9.1
- env: COMPILER=clang++ BUILD_TYPE=Debug
# Xcode 9.0 earliest C++17 support
- name: AppleClang Xcode-9.0 C++17 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
os: osx
osx_image: xcode9.1
compiler: clang
osx_image: xcode9 # AppleClang 9.1.0 same compiler in Xcode 9.0, 9.1 and 9.2
- name: AppleClang Xcode-9.0 C++17 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
os: osx
osx_image: xcode9
- name: AppleClang Xcode-9.0 C++14 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode9
- name: AppleClang Xcode-9.0 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode9
- env: COMPILER=clang++ BUILD_TYPE=Release
# Xcode 9.4
- name: AppleClang Xcode-9.4 C++14 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode9.1
compiler: clang
osx_image: xcode9.4 # AppleClang 9.1.0 same compiler as Xcode 9.3
- name: AppleClang Xcode-9.4 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode9.4
- name: AppleClang Xcode-9.4 C++17 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
os: osx
osx_image: xcode9.4
- name: AppleClang Xcode-9.4 C++17 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
os: osx
osx_image: xcode9.4
# Xcode 10.1
- name: AppleClang Xcode-10.1 C++14 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode10.1 # AppleClang 10.0.0 same compiler as Xcode 10.0
- name: AppleClang Xcode-10.1 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode10.1
- name: AppleClang Xcode-10.1 C++17 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
os: osx
osx_image: xcode10.1
- name: AppleClang Xcode-10.1 C++17 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
os: osx
osx_image: xcode10.1
# Xcode 10.3
- name: AppleClang Xcode-10.3 C++14 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode10.3 # AppleClang 10.0.1 same compiler as Xcode 10.2
- name: AppleClang Xcode-10.3 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode10.3
- name: AppleClang Xcode-10.3 C++17 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
os: osx
osx_image: xcode10.3
- name: AppleClang Xcode-10.3 C++17 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
os: osx
osx_image: xcode10.3
# Xcode 11.3
- name: AppleClang Xcode-11.3 C++17 Debug
stage: Latest
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=17
os: osx
osx_image: xcode11.3 # AppleClang 11.0.0 linker update / same as Xcode 11.2
- name: AppleClang Xcode-11.3 C++17 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=17
os: osx
osx_image: xcode11.3
- name: AppleClang Xcode-11.3 C++14 Debug
env: BUILD_TYPE=Debug GSL_CXX_STANDARD=14
os: osx
osx_image: xcode11.3
- name: AppleClang Xcode-11.3 C++14 Release
env: BUILD_TYPE=Release GSL_CXX_STANDARD=14
os: osx
osx_image: xcode11.3
##########################################################################
# Clang on Linux
##########################################################################
# Clang 3.6
- env: COMPILER=clang++-3.6 BUILD_TYPE=Debug
- name: Clang-3.6 C++14 Debug
stage: Legacy
dist: xenial
env: CXX=clang++-3.6 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang36
apt:
packages:
- clang-3.6
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- env: COMPILER=clang++-3.6 BUILD_TYPE=Release
- name: Clang-3.6 C++14 Release
dist: xenial
env: CXX=clang++-3.6 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang36
# Clang 3.7
- env: COMPILER=clang++-3.7 BUILD_TYPE=Debug
- name: Clang-3.7 C++14 Debug
dist: xenial
env: CXX=clang++-3.7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang37
apt:
packages:
- clang-3.7
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- env: COMPILER=clang++-3.7 BUILD_TYPE=Release
- name: Clang-3.7 C++14 Release
dist: xenial
env: CXX=clang++-3.7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang37
# Clang 3.8
- env: COMPILER=clang++-3.8 BUILD_TYPE=Debug
- name: Clang-3.8 C++14 Debug
dist: xenial
env: CXX=clang++-3.8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang38
apt:
packages:
- clang-3.8
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- env: COMPILER=clang++-3.8 BUILD_TYPE=Release
- name: Clang-3.8 C++14 Release
dist: xenial
env: CXX=clang++-3.8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang38
# Clang 3.9
- env: COMPILER=clang++-3.9 BUILD_TYPE=Debug
- name: Clang-3.9 C++14 Debug
env: CXX=clang++-3.9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang39
apt:
packages:
- clang-3.9
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- env: COMPILER=clang++-3.9 BUILD_TYPE=Release
- name: Clang-3.9 C++14 Release
env: CXX=clang++-3.9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang39
# Clang 4.0
- env: COMPILER=clang++-4.0 BUILD_TYPE=Debug
- name: Clang-4.0 C++14 Debug
env: CXX=clang++-4.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang40
apt:
packages:
- clang-4.0
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- env: COMPILER=clang++-4.0 BUILD_TYPE=Release
- name: Clang-4.0 C++14 Release
env: CXX=clang++-4.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang40
# Clang 5.0
- env: COMPILER=clang++-5.0 BUILD_TYPE=Debug
addons: &clang40
- name: Clang-5.0 C++14 Debug
env: CXX=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang50
apt:
packages:
- clang-5.0
- g++-5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- name: Clang-5.0 C++14 Release
env: CXX=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang50
- name: Clang-5.0 C++17 Debug
env: CXX=clang++-5.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang50
- name: Clang 5.0 C++17 Release
env: CXX=clang++-5.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang50
- env: COMPILER=clang++-5.0 BUILD_TYPE=Release
addons: *clang40
# Clang 6.0
- name: Clang-6.0 C++14 Debug
env: CXX=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang60
apt:
packages:
- clang-6.0
- name: Clang 6.0 C++14 Release
env: CXX=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang60
- name: Clang-6.0 C++17 Debug
env: CXX=clang++-6.0 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang60
- name: Clang 6.0 C++17 Release
env: CXX=clang++-6.0 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang60
# Clang 7 (default on Xenial and Bionic images)
- name: Clang-7 C++14 Debug
env: CXX=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=14
- name: Clang-7 C++14 Release
env: CXX=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=14
- name: Clang-7 C++17 Debug
env: CXX=clang++ BUILD_TYPE=Debug GSL_CXX_STANDARD=17
- name: Clang-7 C++17 Release
env: CXX=clang++ BUILD_TYPE=Release GSL_CXX_STANDARD=17
# Clang 8
- name: Clang-8 C++14 Debug
env: CXX=clang++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang8
apt:
sources:
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main'
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
packages:
- clang-8
- name: Clang-8 C++14 Release
env: CXX=clang++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang8
- name: Clang-8 C++17 Debug
env: CXX=clang++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang8
- name: Clang-8 C++17 Release
env: CXX=clang++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang8
# Clang 9
- name: Clang-9 C++14 Debug
env: CXX=clang++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang9
apt:
sources:
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
packages:
- clang-9
- name: Clang-9 C++14 Release
env: CXX=clang++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang9
- name: Clang-9 C++17 Debug
env: CXX=clang++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang9
- name: Clang-9 C++17 Release
env: CXX=clang++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang9
# Clang 10
- name: Clang-10 C++14 Debug
stage: Latest
env: CXX=clang++-10 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &clang10
apt:
sources:
- sourceline: 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-10 main'
key_url: https://apt.llvm.org/llvm-snapshot.gpg.key
packages:
- clang-10
- name: Clang-10 C++14 Release
env: CXX=clang++-10 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *clang10
- name: Clang-10 C++17 Debug
env: CXX=clang++-10 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *clang10
- name: Clang-10 C++17 Release
env: CXX=clang++-10 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *clang10
##########################################################################
# GCC on Linux
##########################################################################
# GCC 5
- env: COMPILER=g++-5 BUILD_TYPE=Debug
addons: &gcc5
apt:
packages: g++-5
sources:
- ubuntu-toolchain-r-test
- env: COMPILER=g++-5 BUILD_TYPE=Release
addons: *gcc5
# GCC 5 (default on the Xenial image)
- name: GCC-5 C++14 Debug
stage: Legacy
dist: xenial
env: CXX=g++-5 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
- name: GCC-5 C++14 Release
dist: xenial
env: CXX=g++-5 BUILD_TYPE=Release GSL_CXX_STANDARD=14
# GCC 6
- env: COMPILER=g++-6 BUILD_TYPE=Debug
- name: GCC-6 C++14 Debug
env: CXX=g++-6 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &gcc6
apt:
packages: g++-6
sources:
- ubuntu-toolchain-r-test
- env: COMPILER=g++-6 BUILD_TYPE=Release
- name: GCC-6 C++14 Release
env: CXX=g++-6 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *gcc6
# Currently fails due to #525
## GCC 7
#- env: COMPILER=g++-7 BUILD_TYPE=Debug
# addons: &gcc7
# apt:
# packages: g++-7
# sources:
# - ubuntu-toolchain-r-test
# GCC 7 (default on the Bionic image)
- name: GCC-7 C++14 Debug
env: CXX=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
- name: GCC-7 C++14 Release
env: CXX=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=14
- name: GCC-7 C++17 Debug
env: CXX=g++-7 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
- name: GCC-7 C++17 Release
env: CXX=g++-7 BUILD_TYPE=Release GSL_CXX_STANDARD=17
#- env: COMPILER=g++-7 BUILD_TYPE=Release
# addons: *gcc7
# GCC 8
- name: GCC-8 C++14 Debug
env: CXX=g++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &gcc8
apt:
packages: g++-8
- name: GCC-8 C++14 Release
env: CXX=g++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *gcc8
- name: GCC-8 C++17 Debug
env: CXX=g++-8 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *gcc8
- name: GCC-8 C++17 Release
env: CXX=g++-8 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *gcc8
# GCC 9
- name: GCC-9 C++14 Debug
stage: Latest
env: CXX=g++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=14
addons: &gcc9
apt:
sources:
- sourceline: ppa:ubuntu-toolchain-r/test
packages:
- g++-9
- name: GCC-9 C++14 Release
env: CXX=g++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=14
addons: *gcc9
- name: GCC-9 C++17 Debug
env: CXX=g++-9 BUILD_TYPE=Debug GSL_CXX_STANDARD=17
addons: *gcc9
- name: GCC-9 C++17 Release
env: CXX=g++-9 BUILD_TYPE=Release GSL_CXX_STANDARD=17
addons: *gcc9
before_install:
- |
# Configuration
JOBS=2 # Travis machines have 2 cores
# Dependencies required by the CI (cached directory)
DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- |
# Setup
mkdir -p "${DEPS_DIR:?}" && cd "${DEPS_DIR:?}"
mkdir -p ~/tools && cd ~/tools
if [[ ${TRAVIS_OS_NAME:?} == "osx" ]]; then
export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
fi
- |
# Helper functions
# usage: if [[ $(check_url '<url>') ]]; then ...
function check_url {( set +e
if [[ "$1" =~ 'github.com' ]]; then # check for first byte
if curl --fail --silent --output /dev/null --connect-timeout 12 --range 0-0 "$1"
then echo true; fi
else # request head
if curl --fail --silent --output /dev/null --connect-timeout 12 --head "$1"
then echo true; fi
fi
return
)}
install:
# Set the ${CXX} variable properly
- export CXX=${COMPILER}
- ${CXX} --version
# Dependencies required by the CI are installed in ${TRAVIS_BUILD_DIR}/deps/
- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps"
- mkdir -p "${DEPS_DIR}"
- cd "${DEPS_DIR}"
# Travis machines have 2 cores
- JOBS=2
############################################################################
# Install a recent CMake (unless already installed on OS X)
# Install a different CMake version (or several)
############################################################################
- CMAKE_VERSION=3.7.2
- |
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
CMAKE_URL="https://cmake.org/files/v${CMAKE_VERSION%.[0-9]}/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz"
mkdir cmake && travis_retry wget --no-check-certificate -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C cmake
export PATH=${DEPS_DIR}/cmake/bin:${PATH}
else
brew install cmake || brew upgrade cmake
# Install CMake versions
( set -euo pipefail
if [[ ${CMAKE_VERSION:-} ]]; then
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
OS="Linux"; EXT="sh"
if [[ ! ("${CMAKE_VERSION:-}" =~ .+[' '].+) ]]; then
# Single entry -> default CMake version
CMAKE_DEFAULT_DIR="/usr/local"
fi
elif [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then OS="Darwin"; EXT="tar.gz"
else echo "CMake install not supported for this OS."; exit 1
fi
CMAKE_INSTALLER="install-cmake.${EXT}"
fi
for VERSION in ${CMAKE_VERSION:-}; do
CMAKE_URL="https://github.com/Kitware/CMake/releases/download/v${VERSION}/cmake-${VERSION}-${OS}-x86_64.${EXT}"
if [[ $(check_url "$CMAKE_URL") ]]; then
curl -sSL ${CMAKE_URL} -o ${CMAKE_INSTALLER}
CMAKE_DIR="${CMAKE_DEFAULT_DIR:-"${HOME}/tools/cmake-${VERSION}"}"
mkdir -p ${CMAKE_DIR}
if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then
chmod +x ${CMAKE_INSTALLER}
sudo ./${CMAKE_INSTALLER} --prefix=${CMAKE_DIR} --skip-license
else # OSX
mkdir -p ./CMake_tmp
tar --extract --gzip --file=${CMAKE_INSTALLER} --directory=./CMake_tmp
mv ./CMake_tmp/*/CMake.app/Contents/* ${CMAKE_DIR}
fi
rm --recursive --force ./CMake_tmp ${CMAKE_INSTALLER}
else echo 'Invalid url!'; echo "Version: ${VERSION}"
fi
done
)
if [[ ${CMAKE_VERSION:-} && "${TRAVIS_OS_NAME:?}" == "osx" && ! ("${CMAKE_VERSION:-}" =~ .+[' '].+) ]]
then # Single entry -> default CMake version
export PATH=${HOME}/tools/cmake-${CMAKE_VERSION:?}/bin:$PATH
fi
CMAKE_path=("cmake") # start with installed CMake version
for VERSION in ${CMAKE_VERSION:-}; do
tmp_path="$HOME/tools/cmake-${VERSION:?}/bin/cmake"
if [[ -x "$(command -v ${tmp_path:?})" ]]; then CMAKE_path+=("${tmp_path:?}"); fi
done
function test_CMake_generate {
# $1: cmake or full path to cmake
shopt -s extglob
if [[ "$1" == "cmake" || -x "$(command -v $1)" && "$1" =~ .*cmake$ ]]; then
echo "----------------"
$1 --version
echo "Configuration = ${BUILD_TYPE:-Debug}"
$1 -DCMAKE_BUILD_TYPE=${BUILD_TYPE:-Debug} ${CMAKE_GEN_FLAGS[@]:?} ..
rm -rf !(tests/googletest-*)
if [[ ! ${BUILD_TYPE:-} ]]; then echo "" && echo "Configuration = Release"
$1 -DCMAKE_BUILD_TYPE=Release ${CMAKE_GEN_FLAGS[@]:?} ..
rm -rf !(tests/googletest-*)
fi
else echo "Non existing command: $1"
fi
}
- |
# CMake wrapper (Trusty, Xenial & Bionic); restore default behaviour.
if [[ "${TRAVIS_OS_NAME:?}" == "linux" &&
"$(lsb_release --codename)" =~ (trusty|xenial|bionic)$ ]]
then
if [[ -x $(command -v /usr/local/bin/cmake) ]]; then
function cmake { command /usr/local/bin/cmake $@; }
elif [[ -x $(command -v /usr/bin/cmake) ]]; then
function cmake { command /usr/bin/cmake $@; }
fi
fi
- cmake --version
############################################################################
# [linux]: Install the right version of libc++
# Based on https://github.com/ldionne/hana/blob/master/.travis.yml
############################################################################
- |
LLVM_INSTALL=${DEPS_DIR}/llvm/install
LLVM_INSTALL=${DEPS_DIR:?}/llvm/install
# if in linux and compiler clang and llvm not installed
if [[ "${TRAVIS_OS_NAME}" == "linux" && "${CXX%%+*}" == "clang" && -n "$(ls -A ${LLVM_INSTALL})" ]]; then
if [[ "${TRAVIS_OS_NAME:?}" == "linux" && "${CXX%%+*}" == "clang" && -n "$(ls -A ${LLVM_INSTALL:?})" ]]; then
if [[ "${CXX}" == "clang++-3.6" ]]; then LLVM_VERSION="3.6.2";
elif [[ "${CXX}" == "clang++-3.7" ]]; then LLVM_VERSION="3.7.1";
elif [[ "${CXX}" == "clang++-3.8" ]]; then LLVM_VERSION="3.8.1";
@@ -228,12 +535,17 @@ install:
fi
before_script:
# have CMake to generate build files
- cd "${TRAVIS_BUILD_DIR}"
- mkdir build && cd build
- cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
- |
cd "${TRAVIS_BUILD_DIR:?}"
mkdir build && cd build
if [[ ${GSL_CXX_STANDARD:-} ]]; then
CMAKE_GEN_FLAGS=("-DGSL_CXX_STANDARD=$GSL_CXX_STANDARD")
fi
CMAKE_GEN_FLAGS+=("-Wdev -Werror=dev --warn-uninitialized")
script:
# generate build files
- cmake .. -DCMAKE_BUILD_TYPE=${BUILD_TYPE:?} ${CMAKE_GEN_FLAGS[@]:?}
# build and run tests
- cmake --build . -- -j${JOBS}
- ctest --output-on-failure -j${JOBS}
+56 -27
View File
@@ -1,10 +1,13 @@
cmake_minimum_required(VERSION 3.7)
cmake_minimum_required(VERSION 3.1.3...3.16)
project(GSL CXX)
include(ExternalProject)
find_package(Git)
# Use GNUInstallDirs to provide the right locations on all platforms
include(GNUInstallDirs)
# creates a library GSL which is an interface (header files only)
add_library(GSL INTERFACE)
@@ -14,22 +17,28 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(GSL_STANDALONE_PROJECT ON)
endif ()
set(GSL_CXX_STANDARD "14" CACHE STRING "Use c++ standard")
set(GSL_CXX_STD "cxx_std_${GSL_CXX_STANDARD}")
if (MSVC)
set(GSL_CXX_STD_OPT "-std:c++${GSL_CXX_STANDARD}")
else()
set(GSL_CXX_STD_OPT "-std=c++${GSL_CXX_STANDARD}")
endif()
# when minimum version required is 3.8.0 remove if below
# both branches do exactly the same thing
if (CMAKE_VERSION VERSION_LESS 3.7.9)
if (NOT MSVC)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
if(COMPILER_SUPPORTS_CXX14)
target_compile_options(GSL INTERFACE "-std=c++14")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++14 support. Please use a different C++ compiler.")
endif()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("${GSL_CXX_STD_OPT}" COMPILER_SUPPORTS_CXX_STANDARD)
if(COMPILER_SUPPORTS_CXX_STANDARD)
target_compile_options(GSL INTERFACE "${GSL_CXX_STD_OPT}")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no c++${GSL_CXX_STANDARD} support. Please use a different C++ compiler.")
endif()
else ()
# set the GSL library to be compiled only with c++14
target_compile_features(GSL INTERFACE cxx_std_14)
target_compile_features(GSL INTERFACE "${GSL_CXX_STD}")
# on *nix systems force the use of -std=c++XX instead of -std=gnu++XX (default)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
@@ -39,33 +48,53 @@ target_compile_definitions(GSL INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
# remove unnecessary warnings about unchecked iterators
_SCL_SECURE_NO_WARNINGS
# remove deprecation warnings about std::uncaught_exception() (from catch)
_SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
>
)
# add include folders to the library and targets that consume it
target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE:
${CMAKE_CURRENT_SOURCE_DIR}/include
>
)
if (MSVC_IDE)
option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
# the SYSTEM keyword suppresses warnings for users of the library
if(GSL_STANDALONE_PROJECT)
target_include_directories(GSL INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
else()
set(VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
endif()
# add natvis file to the library so it will automatically be loaded into Visual Studio
if(VS_ADD_NATIVE_VISUALIZERS)
target_sources(GSL INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis
target_include_directories(GSL SYSTEM INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
endif()
if (CMAKE_VERSION VERSION_GREATER 3.7.8)
if (MSVC_IDE)
option(VS_ADD_NATIVE_VISUALIZERS "Configure project to use Visual Studio native visualizers" TRUE)
else()
set(VS_ADD_NATIVE_VISUALIZERS FALSE CACHE INTERNAL "Native visualizers are Visual Studio extension" FORCE)
endif()
# add natvis file to the library so it will automatically be loaded into Visual Studio
if(VS_ADD_NATIVE_VISUALIZERS)
target_sources(GSL INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GSL.natvis>
)
endif()
endif()
install(TARGETS GSL EXPORT Microsoft.GSLConfig)
install(
DIRECTORY include/gsl
DESTINATION include
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
# Make library importable by other projects
install(EXPORT Microsoft.GSLConfig NAMESPACE Microsoft.GSL:: DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/Microsoft.GSL)
export(TARGETS GSL NAMESPACE Microsoft.GSL:: FILE Microsoft.GSLConfig.cmake)
# Add Microsoft.GSL::GSL alias for GSL so that dependents can be agnostic about
# whether GSL was added via `add_subdirectory` or `find_package`
add_library(Microsoft.GSL::GSL ALIAS GSL)
option(GSL_TEST "Generate tests." ${GSL_STANDALONE_PROJECT})
if (GSL_TEST)
+18
View File
@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [
"msvc_x64_x64"
],
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"cmakeCommandArgs": "-DGSL_CXX_STANDARD=17",
"buildCommandArgs": "-v",
"ctestCommandArgs": "",
"codeAnalysisRuleset": "CppCoreCheckRules.ruleset"
}
]
}
+2 -2
View File
@@ -1,6 +1,6 @@
## Contributing to the Guideline Support Library
## Contributing to the Guidelines Support Library
The Guideline Support Library (GSL) contains functions and types that are suggested for use by the
The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines). GSL design changes are made only as a result of modifications to the Guidelines.
GSL is accepting contributions that improve or refine any of the types in this library as well as ports to other platforms. Changes should have an issue
+34 -5
View File
@@ -1,6 +1,6 @@
# GSL: Guideline Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
# GSL: Guidelines Support Library [![Build Status](https://travis-ci.org/Microsoft/GSL.svg?branch=master)](https://travis-ci.org/Microsoft/GSL) [![Build status](https://ci.appveyor.com/api/projects/status/github/Microsoft/GSL?svg=true)](https://ci.appveyor.com/project/neilmacintosh/GSL)
The Guideline Support Library (GSL) contains functions and types that are suggested for use by the
The Guidelines Support Library (GSL) contains functions and types that are suggested for use by the
[C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) maintained by the [Standard C++ Foundation](https://isocpp.org).
This repo contains Microsoft's implementation of GSL.
@@ -18,7 +18,7 @@ other platforms. Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for more inform
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
# Usage of Third Party Libraries
This project makes use of the [Catch](https://github.com/philsquared/catch) testing library. Please see the [ThirdPartyNotices.txt](./ThirdPartyNotices.txt) file for details regarding the licensing of Catch.
This project makes use of the [Google Test](https://github.com/google/googletest) testing library. Please see the [ThirdPartyNotices.txt](./ThirdPartyNotices.txt) file for details regarding the licensing of Google Test.
# Quick Start
## Supported Platforms
@@ -27,9 +27,17 @@ The test suite that exercises GSL has been built and passes successfully on the
* Windows using Visual Studio 2015
* Windows using Visual Studio 2017
* Windows using Clang/LLVM 3.6
* Windows using Clang/LLVM 7.0.0
* Windows using GCC 5.1
* GNU/Linux using Clang/LLVM 3.6
* Windows using Intel C++ Compiler 18.0
* GNU/Linux using Clang/LLVM 3.6-3.9
* GNU/Linux using Clang/LLVM 4.0
* GNU/Linux using Clang/LLVM 5.0
* GNU/Linux using Clang/LLVM 6.0
* GNU/Linux using Clang/LLVM 7.0
* GNU/Linux using GCC 5.1
* OS X Mojave 10.14.4 using Apple LLVM version 10.0.0 (10.0.1.10010046)
* OS X Mojave 10.14.3 using Apple LLVM version 10.0.0 (clang-1000.11.45.5)
* OS X Yosemite using Xcode with Apple Clang 7.0.0.7000072
* OS X Yosemite using GCC-5.2.0
* OS X Sierra 10.12.4 using Apple LLVM version 8.1.0 (Clang-802.0.42)
@@ -45,7 +53,7 @@ contributing any changes that were necessary back to this project to benefit the
## Building the tests
To build the tests, you will require the following:
* [CMake](http://cmake.org), version 3.7 or later to be installed and in your PATH.
* [CMake](http://cmake.org), version 3.1.3 (3.2.3 for AppleClang) or later to be installed and in your PATH.
These steps assume the source code of this repository has been cloned into a directory named `c:\GSL`.
@@ -69,6 +77,18 @@ These steps assume the source code of this repository has been cloned into a dir
All tests should pass - indicating your platform is fully supported and you are ready to use the GSL types!
## Building GSL - Using vcpkg
You can download and install GSL using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install ms-gsl
The GSL port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Using the libraries
As the types are entirely implemented inline in headers, there are no linking requirements.
@@ -89,5 +109,14 @@ Include the library using:
#include <gsl/gsl>
## Usage in CMake
The library provides a Config file for CMake, once installed it can be found via
find_package(Microsoft.GSL CONFIG)
Which, when successful, will add library target called `Microsoft.GSL::GSL` which you can use via the usual
`target_link_libraries` mechanism.
## Debugging visualization support
For Visual Studio users, the file [GSL.natvis](./GSL.natvis) in the root directory of the repository can be added to your project if you would like more helpful visualization of GSL types in the Visual Studio debugger than would be offered by default.
+33 -31
View File
@@ -2,38 +2,40 @@
THIRD-PARTY SOFTWARE NOTICES AND INFORMATION
Do Not Translate or Localize
GSL: Guideline Support Library incorporates third party material from the projects listed below. The original copyright notice and the license under which Microsoft received such third party material are set forth below. Microsoft reserves all other rights not expressly granted, whether by implication, estoppel or otherwise.
GSL: Guidelines Support Library incorporates third party material from the projects listed below.
-------------------------------------------------------------------------------
Software: Google Test
Owner: Google Inc.
Source URL: github.com/google/googletest
License: BSD 3 - Clause
Text:
Copyright 2008, Google Inc.
All rights reserved.
1. Catch (https://github.com/philsquared/Catch)
%% Catch NOTICES, INFORMATION, AND LICENSE BEGIN HERE
=========================================
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
=========================================
END OF Catch NOTICES, INFORMATION, AND LICENSE
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-------------------------------------------------------------------------------
+96 -15
View File
@@ -11,35 +11,116 @@ configuration:
image:
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019
environment:
NINJA_TAG: v1.8.2
NINJA_SHA512: 9B9CE248240665FCD6404B989F3B3C27ED9682838225E6DC9B67B551774F251E4FF8A207504F941E7C811E7A8BE1945E7BCB94472A335EF15E23A0200A32E6D5
NINJA_PATH: C:\Tools\ninja\ninja-%NINJA_TAG%
VCVAR2015: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat'
VCVAR2017: 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat'
VCVAR2019: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat'
matrix:
- GSL_CXX_STANDARD: 14
USE_TOOLSET: MSVC
USE_GENERATOR: MSBuild
- GSL_CXX_STANDARD: 17
USE_TOOLSET: MSVC
USE_GENERATOR: MSBuild
- GSL_CXX_STANDARD: 14
USE_TOOLSET: LLVM
USE_GENERATOR: Ninja
- GSL_CXX_STANDARD: 17
USE_TOOLSET: LLVM
USE_GENERATOR: Ninja
matrix:
exclude:
- image: Visual Studio 2015
GSL_CXX_STANDARD: 17
- image: Visual Studio 2015
USE_TOOLSET: LLVM
USE_GENERATOR: MSBuild
cache:
- C:\cmake-3.8.0-win32-x86
- C:\cmake-3.14.4-win32-x86
- C:\Tools\ninja
install:
- ps: |
if (![IO.File]::Exists("C:\cmake-3.8.0-win32-x86\bin\cmake.exe")) {
Start-FileDownload 'https://cmake.org/files/v3.8/cmake-3.8.0-win32-x86.zip'
7z x -y cmake-3.8.0-win32-x86.zip -oC:\
if (![IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
Start-FileDownload `
"https://github.com/ninja-build/ninja/releases/download/$env:NINJA_TAG/ninja-win.zip"
$hash = (Get-FileHash ninja-win.zip -Algorithm SHA512).Hash
if ($env:NINJA_SHA512 -eq $hash) {
7z e -y -bso0 ninja-win.zip -o"$env:NINJA_PATH"
} else { Write-Warning "Ninja download hash changed!"; Write-Output "$hash" }
}
if ([IO.File]::Exists("$env:NINJA_PATH\ninja.exe")) {
$env:PATH = "$env:NINJA_PATH;$env:PATH"
} else { Write-Warning "Failed to find ninja.exe in expected location." }
if ($env:USE_TOOLSET -ne "LLVM") {
if (![IO.File]::Exists("C:\cmake-3.14.0-win32-x86\bin\cmake.exe")) {
Start-FileDownload 'https://cmake.org/files/v3.14/cmake-3.14.4-win32-x86.zip'
7z x -y -bso0 cmake-3.14.4-win32-x86.zip -oC:\
}
$env:PATH="C:\cmake-3.14.4-win32-x86\bin;$env:PATH"
}
$env:PATH="C:\cmake-3.8.0-win32-x86\bin;$env:PATH"
before_build:
- ps: |
mkdir build
cd build
if ("$env:APPVEYOR_JOB_NAME" -match "Image: Visual Studio 2015") {
$env:generator="Visual Studio 14 2015"
if ("$env:USE_GENERATOR" -eq "Ninja") {
$GeneratorFlags = '-k 10'
$Architecture = $env:PLATFORM
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
$env:VCVARSALL = "`"$env:VCVAR2015`" $Architecture"
} elseif ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
$env:VCVARSALL = "`"$env:VCVAR2017`" $Architecture"
} else {
$env:VCVARSALL = "`"$env:VCVAR2019`" $Architecture"
}
$env:CMakeGenFlags = "-G Ninja -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
} else {
$env:generator="Visual Studio 15 2017"
$GeneratorFlags = '/m /v:minimal'
if ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2015") {
$Generator = 'Visual Studio 14 2015'
} elseif ("$env:APPVEYOR_BUILD_WORKER_IMAGE" -eq "Visual Studio 2017") {
$Generator = 'Visual Studio 15 2017'
} else {
$Generator = 'Visual Studio 16 2019'
}
if ("$env:PLATFORM" -eq "x86") {
$Architecture = "Win32"
} else {
$Architecture = "x64"
}
if ("$env:USE_TOOLSET" -eq "LLVM") {
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -T llvm -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
} else {
$env:CMakeGenFlags = "-G `"$Generator`" -A $Architecture -DGSL_CXX_STANDARD=$env:GSL_CXX_STANDARD"
}
}
if ($env:PLATFORM -eq "x64") {
$env:generator="$env:generator Win64"
if ("$env:USE_TOOLSET" -eq "LLVM") {
$env:CC = "clang-cl"
$env:CXX = "clang-cl"
if ("$env:PLATFORM" -eq "x86") {
$env:CFLAGS = "-m32";
$env:CXXFLAGS = "-m32";
} else {
$env:CFLAGS = "-m64";
$env:CXXFLAGS = "-m64";
}
}
echo generator="$env:generator"
cmake .. -G "$env:generator"
$env:CMakeBuildFlags = "--config $env:CONFIGURATION -- $GeneratorFlags"
- mkdir build
- cd build
- if %USE_GENERATOR%==Ninja (call %VCVARSALL%)
- echo %CMakeGenFlags%
- cmake .. %CMakeGenFlags%
build_script:
- cmake --build . --config %CONFIGURATION% -- /m /v:minimal
- echo %CMakeBuildFlags%
- cmake --build . %CMakeBuildFlags%
test_script:
- ctest -j2
+5 -7
View File
@@ -31,17 +31,14 @@
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4996) // unsafe use of std::copy_n
// 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>
// Note: this will generate faster code than std::copy using span iterator in older msvc+stl
// not necessary for msvc since VS2017 15.8 (_MSC_VER >= 1915)
template <class SrcElementType, std::size_t SrcExtent, class DestElementType,
std::size_t DestExtent>
void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent> dest)
{
static_assert(std::is_assignable<decltype(*dest.data()), decltype(*src.data())>::value,
@@ -51,6 +48,7 @@ void copy(span<SrcElementType, SrcExtent> src, span<DestElementType, DestExtent>
"Source range is longer than target range");
Expects(dest.size() >= src.size());
GSL_SUPPRESS(stl.1) // NO-FORMAT: attribute
std::copy_n(src.data(), src.size(), dest.data());
}
+45 -57
View File
@@ -17,29 +17,40 @@
#ifndef GSL_CONTRACTS_H
#define GSL_CONTRACTS_H
#include <exception>
#include <stdexcept> // for logic_error
//
// Temporary until MSVC STL supports no-exceptions mode.
// Currently terminate is a no-op in this mode, so we add termination behavior back
//
#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
#if defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
#endif
#include <intrin.h>
#define RANGE_CHECKS_FAILURE 0
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Winvalid-noreturn"
#endif // defined(__clang__)
#else // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
#include <exception>
#endif // defined(_MSC_VER) && (defined(_KERNEL_MODE) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS))
//
// There are three configuration options for this GSL implementation's behavior
// when pre/post conditions on the GSL types are violated:
// make suppress attributes parse for some compilers
// Hopefully temporary until suppression standardization occurs
//
// 1. GSL_TERMINATE_ON_CONTRACT_VIOLATION: std::terminate will be called (default)
// 2. GSL_THROW_ON_CONTRACT_VIOLATION: a gsl::fail_fast exception will be thrown
// 3. GSL_UNENFORCED_ON_CONTRACT_VIOLATION: nothing happens
//
#if !(defined(GSL_THROW_ON_CONTRACT_VIOLATION) || defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) || \
defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION))
#define GSL_TERMINATE_ON_CONTRACT_VIOLATION
#endif
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // _MSC_VER
#endif // __clang__
#define GSL_STRINGIFY_DETAIL(x) #x
#define GSL_STRINGIFY(x) GSL_STRINGIFY_DETAIL(x)
@@ -47,10 +58,12 @@
#if defined(__clang__) || defined(__GNUC__)
#define GSL_LIKELY(x) __builtin_expect(!!(x), 1)
#define GSL_UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#define GSL_LIKELY(x) (!!(x))
#define GSL_UNLIKELY(x) (!!(x))
#endif
#endif // defined(__clang__) || defined(__GNUC__)
//
// GSL_ASSUME(cond)
@@ -72,24 +85,28 @@
namespace gsl
{
struct fail_fast : public std::logic_error
{
explicit fail_fast(char const* const message) : std::logic_error(message) {}
};
namespace details
{
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
typedef void (*terminate_handler)();
typedef void(__cdecl* terminate_handler)();
// clang-format off
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute
// clang-format on
[[noreturn]] inline void __cdecl default_terminate_handler()
{
__fastfail(RANGE_CHECKS_FAILURE);
}
inline gsl::details::terminate_handler& get_terminate_handler() noexcept
{
static terminate_handler handler = &abort;
static terminate_handler handler = &default_terminate_handler;
return handler;
}
#endif
#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
[[noreturn]] inline void terminate() noexcept
{
@@ -97,49 +114,20 @@ namespace details
(*gsl::details::get_terminate_handler())();
#else
std::terminate();
#endif
#endif // defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
}
#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
template <typename Exception>
[[noreturn]] void throw_exception(Exception&&)
{
gsl::details::terminate();
}
#else
template <typename Exception>
[[noreturn]] void throw_exception(Exception&& exception)
{
throw exception;
}
#endif
} // namespace details
} // namespace gsl
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) \
: gsl::details::throw_exception(gsl::fail_fast( \
"GSL: " type " failure at " __FILE__ ": " GSL_STRINGIFY(__LINE__))))
#elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond)
#endif
#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond)
#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__)
#pragma clang diagnostic pop
#endif
#endif // GSL_CONTRACTS_H
+47 -12
View File
@@ -17,51 +17,84 @@
#ifndef GSL_BYTE_H
#define GSL_BYTE_H
//
// make suppress attributes work for some compilers
// Hopefully temporary until suppression standardization occurs
//
#if defined(__clang__)
#define GSL_SUPPRESS(x) [[gsl::suppress("x")]]
#else
#if defined(_MSC_VER)
#define GSL_SUPPRESS(x) [[gsl::suppress(x)]]
#else
#define GSL_SUPPRESS(x)
#endif // _MSC_VER
#endif // __clang__
#include <type_traits>
// VS2017 15.8 added support for the __cpp_lib_byte definition
// To do: drop _HAS_STD_BYTE when support for pre 15.8 expires
#ifdef _MSC_VER
#pragma warning(push)
// don't warn about function style casts in byte related operators
#pragma warning(disable : 26493)
// Turn MSVC /analyze rules that generate too much noise. TODO: fix in the tool.
#pragma warning(disable : 26493) // don't use c-style casts // TODO: MSVC suppression in templates does not always work
#ifndef GSL_USE_STD_BYTE
// this tests if we are under MSVC and the standard lib has std::byte and it is enabled
#if defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
#if (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#define GSL_USE_STD_BYTE 1
#else // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
#else // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#define GSL_USE_STD_BYTE 0
#endif // defined(_HAS_STD_BYTE) && _HAS_STD_BYTE
#endif // (defined(_HAS_STD_BYTE) && _HAS_STD_BYTE) || (defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603)
#endif // GSL_USE_STD_BYTE
#else // _MSC_VER
#ifndef GSL_USE_STD_BYTE
#include <cstddef> /* __cpp_lib_byte */
// this tests if we are under GCC or Clang with enough -std:c++1z power to get us std::byte
#if defined(__cplusplus) && (__cplusplus >= 201703L)
// also check if libc++ version is sufficient (> 5.0) or libstc++ actually contains std::byte
#if defined(__cplusplus) && (__cplusplus >= 201703L) && \
(defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) || \
defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
#define GSL_USE_STD_BYTE 1
#include <cstddef>
#else // defined(__cplusplus) && (__cplusplus >= 201703L)
#else // defined(__cplusplus) && (__cplusplus >= 201703L) &&
// (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) ||
// defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
#define GSL_USE_STD_BYTE 0
#endif //defined(__cplusplus) && (__cplusplus >= 201703L)
#endif //defined(__cplusplus) && (__cplusplus >= 201703L) &&
// (defined(__cpp_lib_byte) && (__cpp_lib_byte >= 201603) ||
// defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 5000))
#endif // GSL_USE_STD_BYTE
#endif // _MSC_VER
#endif // _MSC_VER
// Use __may_alias__ attribute on gcc and clang
#if defined __clang__ || (defined(__GNUC__) && __GNUC__ > 5)
#define byte_may_alias __attribute__((__may_alias__))
#else // defined __clang__ || defined __GNUC__
#define byte_may_alias
#endif // defined __clang__ || defined __GNUC__
#if GSL_USE_STD_BYTE
#include <cstddef>
#endif
namespace gsl
{
#if GSL_USE_STD_BYTE
using std::byte;
using std::to_integer;
@@ -69,7 +102,7 @@ using std::to_integer;
// This is a simple definition for now that allows
// use of byte within span<> to be standards-compliant
enum class byte : unsigned char
enum class byte_may_alias byte : unsigned char
{
};
@@ -146,6 +179,8 @@ constexpr byte to_byte_impl(T t) noexcept
return static_cast<byte>(t);
}
template <>
// NOTE: need suppression since c++14 does not allow "return {t}"
// GSL_SUPPRESS(type.4) // NO-FORMAT: attribute // TODO: suppression does not work
constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
{
return byte(t);
+32 -18
View File
@@ -21,12 +21,11 @@
#include <array>
#include <cstddef> // for ptrdiff_t, size_t
#include <exception> // for exception
#include <initializer_list> // for initializer_list
#include <type_traits> // for is_signed, integral_constant
#include <utility> // for forward
#include <utility> // for exchange, forward
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
@@ -34,8 +33,14 @@
#if _MSC_VER < 1910
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#endif // _MSC_VER < 1910
#endif // _MSC_VER
#if (defined(_MSC_VER) && _MSC_VER < 1910) || (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 6)
#define GSL_CONSTEXPR_NARROW 0
#else
#define GSL_CONSTEXPR_NARROW 1
#endif
namespace gsl
{
@@ -53,14 +58,13 @@ class final_action
public:
explicit final_action(F f) noexcept : f_(std::move(f)) {}
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_)
{
other.invoke_ = false;
}
final_action(final_action&& other) noexcept : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false)) {}
final_action(const final_action&) = delete;
final_action& operator=(const final_action&) = delete;
final_action& operator=(final_action&&) = delete;
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws
~final_action() noexcept
{
if (invoke_) f_();
@@ -68,12 +72,11 @@ public:
private:
F f_;
bool invoke_ {true};
bool invoke_{true};
};
// finally() - convenience function to generate a final_action
template <class F>
final_action<F> finally(const F& f) noexcept
{
return final_action<F>(f);
@@ -87,6 +90,7 @@ final_action<F> finally(F&& f) noexcept
// narrow_cast(): a searchable way to do narrowing casts of values
template <class T, class U>
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
constexpr T narrow_cast(U&& u) noexcept
{
return static_cast<T>(std::forward<U>(u));
@@ -103,16 +107,21 @@ namespace details
: public std::integral_constant<bool, std::is_signed<T>::value == std::is_signed<U>::value>
{
};
}
} // namespace details
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
template <class T, class U>
T narrow(U u)
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
#if GSL_CONSTEXPR_NARROW
constexpr
#endif
T narrow(U u) noexcept(false)
{
T t = narrow_cast<T>(u);
if (static_cast<U>(t) != u) gsl::details::throw_exception(narrowing_error());
if (static_cast<U>(t) != u) throw narrowing_error{};
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
gsl::details::throw_exception(narrowing_error());
throw narrowing_error{};
return t;
}
@@ -120,21 +129,26 @@ T narrow(U u)
// at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
//
template <class T, std::size_t N>
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
constexpr T& at(T (&arr)[N], const index i)
{
Expects(i >= 0 && i < narrow_cast<index>(N));
return arr[static_cast<std::size_t>(i)];
return arr[narrow_cast<std::size_t>(i)];
}
template <class Cont>
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
{
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
using size_type = decltype(cont.size());
return cont[static_cast<size_type>(i)];
return cont[narrow_cast<size_type>(i)];
}
template <class T>
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
constexpr T at(const std::initializer_list<T> cont, const index i)
{
Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
@@ -143,7 +157,7 @@ constexpr T at(const std::initializer_list<T> cont, const index i)
} // namespace gsl
#if defined(_MSC_VER)
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER < 1910
#undef constexpr
#pragma pop_macro("constexpr")
+500 -455
View File
File diff suppressed because it is too large Load Diff
+119 -5
View File
@@ -25,7 +25,7 @@
#include <system_error> // for hash
#include <type_traits> // for enable_if_t, is_convertible, is_assignable
#if defined(_MSC_VER) && _MSC_VER < 1910
#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#pragma push_macro("constexpr")
#define constexpr /*constexpr*/
@@ -77,12 +77,17 @@ public:
Expects(ptr_ != nullptr);
}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr not_null(T u) : ptr_(u)
{
Expects(ptr_ != nullptr);
}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr not_null(const not_null<U>& other) : not_null(other.get())
{
}
not_null(not_null&& other) = default;
not_null(const not_null& other) = default;
not_null& operator=(const not_null& other) = default;
@@ -94,7 +99,7 @@ public:
constexpr operator T() const { return get(); }
constexpr T operator->() const { return get(); }
constexpr decltype(auto) operator*() const { return *get(); }
constexpr decltype(auto) operator*() const { return *get(); }
// prevents compilation when someone attempts to assign a null pointer constant
not_null(std::nullptr_t) = delete;
@@ -113,6 +118,11 @@ private:
T ptr_;
};
template <class T>
auto make_not_null(T&& t) {
return not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
template <class T>
std::ostream& operator<<(std::ostream& os, const not_null<T>& val)
{
@@ -178,10 +188,114 @@ struct hash<gsl::not_null<T>>
} // namespace std
#if defined(_MSC_VER) && _MSC_VER < 1910
namespace gsl
{
//
// strict_not_null
//
// Restricts a pointer or smart pointer to only hold non-null values,
//
// - provides a strict (i.e. explicit constructor from T) wrapper of not_null
// - to be used for new code that wishes the design to be cleaner and make not_null
// checks intentional, or in old code that would like to make the transition.
//
// To make the transition from not_null, incrementally replace not_null
// by strict_not_null and fix compilation errors
//
// Expect to
// - remove all unneeded conversions from raw pointer to not_null and back
// - make API clear by specifying not_null in parameters where needed
// - remove unnecessary asserts
//
template <class T>
class strict_not_null: public not_null<T>
{
public:
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr explicit strict_not_null(U&& u) :
not_null<T>(std::forward<U>(u))
{}
template <typename = std::enable_if_t<!std::is_same<std::nullptr_t, T>::value>>
constexpr explicit strict_not_null(T u) :
not_null<T>(u)
{}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr strict_not_null(const not_null<U>& other) :
not_null<T>(other)
{}
template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
constexpr strict_not_null(const strict_not_null<U>& other) :
not_null<T>(other)
{}
strict_not_null(strict_not_null&& other) = default;
strict_not_null(const strict_not_null& other) = default;
strict_not_null& operator=(const strict_not_null& other) = default;
strict_not_null& operator=(const not_null<T>& other)
{
not_null<T>::operator=(other);
return *this;
}
// prevents compilation when someone attempts to assign a null pointer constant
strict_not_null(std::nullptr_t) = delete;
strict_not_null& operator=(std::nullptr_t) = delete;
// unwanted operators...pointers only point to single objects!
strict_not_null& operator++() = delete;
strict_not_null& operator--() = delete;
strict_not_null operator++(int) = delete;
strict_not_null operator--(int) = delete;
strict_not_null& operator+=(std::ptrdiff_t) = delete;
strict_not_null& operator-=(std::ptrdiff_t) = delete;
void operator[](std::ptrdiff_t) const = delete;
};
// more unwanted operators
template <class T, class U>
std::ptrdiff_t operator-(const strict_not_null<T>&, const strict_not_null<U>&) = delete;
template <class T>
strict_not_null<T> operator-(const strict_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
strict_not_null<T> operator+(const strict_not_null<T>&, std::ptrdiff_t) = delete;
template <class T>
strict_not_null<T> operator+(std::ptrdiff_t, const strict_not_null<T>&) = delete;
template <class T>
auto make_strict_not_null(T&& t) {
return strict_not_null<std::remove_cv_t<std::remove_reference_t<T>>>{std::forward<T>(t)};
}
#if ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
// deduction guides to prevent the ctad-maybe-unsupported warning
template <class T> not_null(T) -> not_null<T>;
template <class T> strict_not_null(T) -> strict_not_null<T>;
#endif // ( defined(__cpp_deduction_guides) && (__cpp_deduction_guides >= 201611L) )
} // namespace gsl
namespace std
{
template <class T>
struct hash<gsl::strict_not_null<T>>
{
std::size_t operator()(const gsl::strict_not_null<T>& value) const { return hash<T>{}(value); }
};
} // namespace std
#if defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#undef constexpr
#pragma pop_macro("constexpr")
#endif // defined(_MSC_VER) && _MSC_VER < 1910
#endif // defined(_MSC_VER) && _MSC_VER < 1910 && !defined(__clang__)
#endif // GSL_POINTERS_H
+396 -351
View File
File diff suppressed because it is too large Load Diff
+198
View File
@@ -0,0 +1,198 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef GSL_SPAN_EXT_H
#define GSL_SPAN_EXT_H
///////////////////////////////////////////////////////////////////////////////
//
// File: span_ext
// Purpose: continue offering features that have been cut from the official
// implementation of span.
// While modernizing gsl::span a number of features needed to be removed to
// be compliant with the design of std::span
//
///////////////////////////////////////////////////////////////////////////////
#include <gsl/gsl_util> // for narrow_cast, narrow
#include <gsl/span> // for span
#include <algorithm> // for lexicographical_compare
#include <cstddef> // for ptrdiff_t, size_t
#include <utility>
namespace gsl
{
// [span.comparison], span comparison operators
template <class ElementType, std::size_t FirstExtent, std::size_t SecondExtent>
constexpr bool operator==(span<ElementType, FirstExtent> l, span<ElementType, SecondExtent> r)
{
return std::equal(l.begin(), l.end(), r.begin(), r.end());
}
template <class ElementType, std::size_t Extent>
constexpr bool operator!=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l == r);
}
template <class ElementType, std::size_t Extent>
constexpr bool operator<(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
}
template <class ElementType, std::size_t Extent>
constexpr bool operator<=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l > r);
}
template <class ElementType, std::size_t Extent>
constexpr bool operator>(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return r < l;
}
template <class ElementType, std::size_t Extent>
constexpr bool operator>=(span<ElementType, Extent> l, span<ElementType, Extent> r)
{
return !(l < r);
}
//
// make_span() - Utility functions for creating spans
//
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* ptr, typename span<ElementType>::size_type count)
{
return span<ElementType>(ptr, count);
}
template <class ElementType>
constexpr span<ElementType> make_span(ElementType* firstElem, ElementType* lastElem)
{
return span<ElementType>(firstElem, lastElem);
}
template <class ElementType, std::size_t N>
constexpr span<ElementType, N> make_span(ElementType (&arr)[N]) noexcept
{
return span<ElementType, N>(arr);
}
template <class Container>
constexpr span<typename Container::value_type> make_span(Container& cont)
{
return span<typename Container::value_type>(cont);
}
template <class Container>
constexpr span<const typename Container::value_type> make_span(const Container& cont)
{
return span<const typename Container::value_type>(cont);
}
template <class Ptr>
constexpr span<typename Ptr::element_type> make_span(Ptr& cont, std::size_t count)
{
return span<typename Ptr::element_type>(cont, count);
}
template <class Ptr>
constexpr span<typename Ptr::element_type> make_span(Ptr& cont)
{
return span<typename Ptr::element_type>(cont);
}
// Specialization of gsl::at for span
template <class ElementType, std::size_t Extent>
constexpr ElementType& at(span<ElementType, Extent> s, index i)
{
// No bounds checking here because it is done in span::operator[] called below
Ensures(i >= 0);
return s[narrow_cast<std::size_t>(i)];
}
// [span.obs] Free observer functions
template <class ElementType, std::size_t Extent>
constexpr std::ptrdiff_t ssize(const span<ElementType, Extent>& s) noexcept
{
return static_cast<std::ptrdiff_t>(s.size());
}
// [span.iter] Free functions for begin/end functions
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::iterator
begin(const span<ElementType, Extent>& s) noexcept
{
return s.begin();
}
template <class ElementType, std::size_t Extent = dynamic_extent>
constexpr typename span<ElementType, Extent>::iterator
end(const span<ElementType, Extent>& s) noexcept
{
return s.end();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rbegin(const span<ElementType, Extent>& s) noexcept
{
return s.rbegin();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
rend(const span<ElementType, Extent>& s) noexcept
{
return s.rend();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::iterator
cbegin(const span<ElementType, Extent>& s) noexcept
{
return s.begin();
}
template <class ElementType, std::size_t Extent = dynamic_extent>
constexpr typename span<ElementType, Extent>::iterator
cend(const span<ElementType, Extent>& s) noexcept
{
return s.end();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
crbegin(const span<ElementType, Extent>& s) noexcept
{
return s.rbegin();
}
template <class ElementType, std::size_t Extent>
constexpr typename span<ElementType, Extent>::reverse_iterator
crend(const span<ElementType, Extent>& s) noexcept
{
return s.rend();
}
} // namespace gsl
#endif // GSL_SPAN_EXT_H
+716 -715
View File
File diff suppressed because it is too large Load Diff
+173 -70
View File
@@ -1,41 +1,86 @@
cmake_minimum_required(VERSION 2.8.7)
cmake_minimum_required(VERSION 3.0.2)
project(GSLTests CXX)
# will make visual studio generated project group files
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
list(APPEND CATCH_CMAKE_ARGS
"-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external"
"-DNO_SELFTEST=true"
configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
execute_process(
COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
)
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download
)
if(result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory(
${CMAKE_CURRENT_BINARY_DIR}/googletest-src
${CMAKE_CURRENT_BINARY_DIR}/googletest-build
EXCLUDE_FROM_ALL
)
if(GIT_FOUND)
# add catch
ExternalProject_Add(
catch
PREFIX ${CMAKE_BINARY_DIR}/catch
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG v2.0.1
CMAKE_ARGS ${CATCH_CMAKE_ARGS}
LOG_DOWNLOAD 1
UPDATE_DISCONNECTED 1
)
else()
# assume catch is installed in a system directory
add_custom_target(catch)
if (MSVC AND (GSL_CXX_STANDARD EQUAL 17))
set(GSL_CPLUSPLUS_OPT -Zc:__cplusplus -permissive-)
endif()
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config INTERFACE)
target_compile_options(gsl_tests_config INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
if(MSVC) # MSVC or simulating MSVC
target_compile_options(gsl_tests_config INTERFACE
${GSL_CPLUSPLUS_OPT}
/EHsc
/W4
/WX
>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
$<$<CXX_COMPILER_ID:MSVC>:
/wd4996 # Use of function or classes marked [[deprecated]]
/wd26409 # CppCoreCheck - GTest
/wd26426 # CppCoreCheck - GTest
/wd26440 # CppCoreCheck - GTest
/wd26446 # CppCoreCheck - prefer gsl::at()
/wd26472 # CppCoreCheck - use gsl::narrow(_cast)
/wd26481 # CppCoreCheck - use span instead of pointer arithmetic
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,1920>: # VS2015
/wd4189 # variable is initialized but not referenced
$<$<NOT:$<CONFIG:Debug>>: # Release, RelWithDebInfo
/wd4702 # Unreachable code
>
>
>
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-covered-switch-default # GTest
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
-Wno-global-constructors # GTest
-Wno-language-extension-token # GTest gtest-port.h
-Wno-missing-braces
-Wno-missing-prototypes
-Wno-shift-sign-overflow # GTest gtest-port.h
-Wno-undef # GTest
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-member-function
-Wno-unused-variable
>
>
)
else()
target_compile_options(gsl_tests_config INTERFACE
-fno-strict-aliasing
-Wall
-Wcast-align
@@ -43,53 +88,80 @@ target_compile_options(gsl_tests_config INTERFACE
-Wctor-dtor-privacy
-Werror
-Wextra
-Wno-missing-braces
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
>
-Wno-deprecated-declarations # Allow tests for [[deprecated]] elements
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-braces
-Wno-covered-switch-default # GTest
-Wno-global-constructors # GTest
-Wno-missing-prototypes
-Wno-padded
-Wno-unknown-attributes
-Wno-used-but-marked-unused # GTest EXPECT_DEATH
-Wno-weak-vtables
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-member-function
-Wno-unused-variable
>
>
$<$<CXX_COMPILER_ID:Clang>:
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,4.99>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
>
>
$<$<CXX_COMPILER_ID:AppleClang>:
$<$<AND:$<VERSION_GREATER:$<CXX_COMPILER_VERSION>,9.1>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,10>>:
$<$<EQUAL:${GSL_CXX_STANDARD},17>:-Wno-undefined-func-template>
>
>
$<$<CXX_COMPILER_ID:GNU>:
-Wdouble-promotion # float implicit to double
-Wlogical-op # suspicious uses of logical operators
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
-Wduplicated-cond # duplicated if-else conditions
-Wmisleading-indentation
-Wnull-dereference
$<$<EQUAL:${GSL_CXX_STANDARD},14>: # no support for [[maybe_unused]]
-Wno-unused-variable
>
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
-Wduplicated-branches # identical if-else branches
>
>
)
endif(MSVC)
# for tests to find the gtest header
target_include_directories(gsl_tests_config SYSTEM INTERFACE
googletest/googletest/include
)
# for tests to find the catch header
target_include_directories(gsl_tests_config INTERFACE
${CMAKE_BINARY_DIR}/external/include
)
# set definitions for tests
target_compile_definitions(gsl_tests_config INTERFACE
GSL_THROW_ON_CONTRACT_VIOLATION
)
# create the main executable for each test. this reduces the compile time
# of each test by pre-compiling catch.
add_library(test_catch STATIC test.cpp)
target_link_libraries(test_catch
GSL
gsl_tests_config
)
add_dependencies(test_catch catch)
set_property(TARGET test_catch PROPERTY FOLDER "GSL_tests")
set_property(TARGET PROPERTY FOLDER "GSL_tests")
function(add_gsl_test name)
add_executable(${name} ${name}.cpp)
target_link_libraries(${name}
GSL
test_catch
gsl_tests_config
gtest_main
)
add_dependencies(${name} catch)
add_test(
${name}
${name}
${name}
${name}
)
# group all tests under GSL_tests
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests")
endfunction()
add_gsl_test(span_tests)
add_gsl_test(span_ext_tests)
add_gsl_test(span_compatibility_tests)
add_gsl_test(multi_span_tests)
add_gsl_test(strided_span_tests)
add_gsl_test(string_span_tests)
@@ -101,6 +173,7 @@ add_gsl_test(utils_tests)
add_gsl_test(owner_tests)
add_gsl_test(byte_tests)
add_gsl_test(algorithm_tests)
add_gsl_test(strict_notnull_tests)
# No exception tests
@@ -114,43 +187,74 @@ endforeach(flag_var)
# this interface adds compile options to how the tests are run
# please try to keep entries ordered =)
add_library(gsl_tests_config_noexcept INTERFACE)
target_compile_options(gsl_tests_config_noexcept INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:
/D_HAS_EXCEPTIONS=0
/wd4702
/wd4577
if(MSVC) # MSVC or simulating MSVC
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
_HAS_EXCEPTIONS=0 # disable exceptions in the Microsoft STL
)
target_compile_options(gsl_tests_config_noexcept INTERFACE
${GSL_CPLUSPLUS_OPT}
/W4
/WX
>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:
-fno-strict-aliasing
$<$<CXX_COMPILER_ID:MSVC>:
/wd4577
/wd4702
/wd26440 # CppCoreCheck - GTest
/wd26446 # CppCoreCheck - prefer gsl::at()
>
$<$<CXX_COMPILER_ID:Clang>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-prototypes
-Wno-unknown-attributes
>
)
else()
target_compile_options(gsl_tests_config_noexcept INTERFACE
-fno-exceptions
-fno-strict-aliasing
-Wall
-Wcast-align
-Wconversion
-Wctor-dtor-privacy
-Werror
-Wextra
-Wno-missing-braces
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wpedantic
-Wshadow
-Wsign-conversion
>
)
# set definitions for tests
target_compile_definitions(gsl_tests_config_noexcept INTERFACE
GSL_TERMINATE_ON_CONTRACT_VIOLATION
)
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-missing-prototypes
-Wno-unknown-attributes
-Wno-weak-vtables
>
$<$<CXX_COMPILER_ID:GNU>:
-Wdouble-promotion # float implicit to double
-Wlogical-op # suspicious uses of logical operators
-Wuseless-cast # casting to its own type
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,6>>:
-Wduplicated-cond # duplicated if-else conditions
-Wmisleading-indentation
-Wnull-dereference
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,7>>:
-Wduplicated-branches # identical if-else branches
>
$<$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>>:
-Wcast-align=strict # increase alignment (i.e. char* to int*)
>
>
)
endif(MSVC)
function(add_gsl_test_noexcept name)
add_executable(${name} ${name}.cpp)
target_link_libraries(${name}
GSL
gsl_tests_config_noexcept
gtest_main
)
add_test(
${name}
@@ -160,5 +264,4 @@ function(add_gsl_test_noexcept name)
set_property(TARGET ${name} PROPERTY FOLDER "GSL_tests_noexcept")
endfunction()
add_gsl_test_noexcept(no_exception_throw_tests)
add_gsl_test_noexcept(no_exception_ensure_tests)
+14
View File
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.0.2)
project(googletest-download NONE)
include(ExternalProject)
ExternalProject_Add(googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
+73 -56
View File
@@ -14,37 +14,42 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHE...
#include <gtest/gtest.h>
#include <gsl/gsl_algorithm> // for copy
#include <gsl/span> // for span
#include <array> // for array
#include <cstddef> // for size_t
namespace gsl {
namespace
{
static constexpr char deathstring[] = "Expected Death";
}
namespace gsl
{
struct fail_fast;
} // namespace gsl
} // namespace gsl
using namespace std;
using namespace gsl;
TEST_CASE("same_type")
TEST(algorithm_tests, 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);
const span<int> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -53,15 +58,16 @@ TEST_CASE("same_type")
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);
const span<int, 5> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -70,15 +76,16 @@ TEST_CASE("same_type")
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);
const span<int> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -87,35 +94,37 @@ TEST_CASE("same_type")
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);
const span<int, 5> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
}
TEST_CASE("compatible_type")
TEST(algorithm_tests, compatible_type)
{
// dynamic source and destination span
{
std::array<short, 5> src{1, 2, 3, 4, 5};
std::array<int, 10> dst{};
span<short> src_span(src);
span<int> dst_span(dst);
const span<short> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -124,15 +133,16 @@ TEST_CASE("compatible_type")
std::array<short, 5> src{1, 2, 3, 4, 5};
std::array<int, 10> dst{};
span<short, 5> src_span(src);
span<int> dst_span(dst);
const span<short, 5> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -141,15 +151,16 @@ TEST_CASE("compatible_type")
std::array<short, 5> src{1, 2, 3, 4, 5};
std::array<int, 10> dst{};
span<short> src_span(src);
span<int, 10> dst_span(dst);
const span<short> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
@@ -158,21 +169,22 @@ TEST_CASE("compatible_type")
std::array<short, 5> src{1, 2, 3, 4, 5};
std::array<int, 10> dst{};
span<short, 5> src_span(src);
span<int, 10> dst_span(dst);
const span<short, 5> src_span(src);
const 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]);
for (std::size_t i = 0; i < src.size(); ++i)
{
EXPECT_TRUE(dst[i] == src[i]);
EXPECT_TRUE(dst[i + src.size()] == src[i]);
}
}
}
#ifdef CONFIRM_COMPILATION_ERRORS
TEST_CASE("incompatible_type")
TEST(algorithm_tests, incompatible_type)
{
std::array<int, 4> src{1, 2, 3, 4};
std::array<int*, 12> dst{};
@@ -190,19 +202,24 @@ TEST_CASE("incompatible_type")
}
#endif
TEST_CASE("small_destination_span")
TEST(algorithm_tests, small_destination_span)
{
std::set_terminate([] {
std::cerr << "Expected Death. small_destination_span";
std::abort();
});
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);
const span<int> src_span_dyn(src);
const span<int, 12> src_span_static(src);
const span<int> dst_span_dyn(dst);
const span<int, 4> dst_span_static(dst);
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_dyn), fail_fast);
CHECK_THROWS_AS(copy(src_span_dyn, dst_span_static), fail_fast);
CHECK_THROWS_AS(copy(src_span_static, dst_span_dyn), fail_fast);
EXPECT_DEATH(copy(src_span_dyn, dst_span_dyn), deathstring);
EXPECT_DEATH(copy(src_span_dyn, dst_span_static), deathstring);
EXPECT_DEATH(copy(src_span_static, dst_span_dyn), deathstring);
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
+26 -11
View File
@@ -14,33 +14,48 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
#include <gtest/gtest.h>
#include <gsl/gsl_assert> // for fail_fast (ptr only), Ensures, Expects
using namespace gsl;
namespace
{
static constexpr char deathstring[] = "Expected Death";
int f(int i)
{
Expects(i > 0 && i < 10);
return i;
}
TEST_CASE("expects")
{
CHECK(f(2) == 2);
CHECK_THROWS_AS(f(10), fail_fast);
}
int g(int i)
{
i++;
Ensures(i > 0 && i < 10);
return i;
}
} // namespace
TEST_CASE("ensures")
TEST(assertion_tests, expects)
{
CHECK(g(2) == 3);
CHECK_THROWS_AS(g(9), fail_fast);
std::set_terminate([] {
std::cerr << "Expected Death. expects";
std::abort();
});
EXPECT_TRUE(f(2) == 2);
EXPECT_DEATH(f(10), deathstring);
}
TEST(assertion_tests, ensures)
{
std::set_terminate([] {
std::cerr << "Expected Death. ensures";
std::abort();
});
EXPECT_TRUE(g(2) == 3);
EXPECT_DEATH(g(9), deathstring);
}
+54 -35
View File
@@ -14,7 +14,7 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK_THROW...
#include <gtest/gtest.h>
#include <gsl/gsl_util> // for at
@@ -23,73 +23,92 @@
#include <initializer_list> // for initializer_list
#include <vector> // for vector
namespace gsl {
struct fail_fast;
} // namespace gsl
namespace
{
static constexpr char deathstring[] = "Expected Death";
}
using gsl::fail_fast;
TEST_CASE("static_array")
TEST(at_tests, static_array)
{
int a[4] = {1, 2, 3, 4};
const int(&c_a)[4] = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[i]);
CHECK(&gsl::at(c_a, i) == &a[i]);
EXPECT_TRUE(&gsl::at(a, i) == &a[i]);
EXPECT_TRUE(&gsl::at(c_a, i) == &a[i]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
std::set_terminate([] {
std::cerr << "Expected Death. static_array";
std::abort();
});
EXPECT_DEATH(gsl::at(a, -1), deathstring);
EXPECT_DEATH(gsl::at(a, 4), deathstring);
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
}
TEST_CASE("std_array")
TEST(at_tests, std_array)
{
std::array<int, 4> a = {1, 2, 3, 4};
const std::array<int, 4>& c_a = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
std::set_terminate([] {
std::cerr << "Expected Death. std_array";
std::abort();
});
EXPECT_DEATH(gsl::at(a, -1), deathstring);
EXPECT_DEATH(gsl::at(a, 4), deathstring);
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
}
TEST_CASE("StdVector")
TEST(at_tests, std_vector)
{
std::vector<int> a = {1, 2, 3, 4};
const std::vector<int>& c_a = a;
for (int i = 0; i < 4; ++i) {
CHECK(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
CHECK(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_TRUE(&gsl::at(a, i) == &a[static_cast<std::size_t>(i)]);
EXPECT_TRUE(&gsl::at(c_a, i) == &a[static_cast<std::size_t>(i)]);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(c_a, 4), fail_fast);
std::set_terminate([] {
std::cerr << "Expected Death. std_vector";
std::abort();
});
EXPECT_DEATH(gsl::at(a, -1), deathstring);
EXPECT_DEATH(gsl::at(a, 4), deathstring);
EXPECT_DEATH(gsl::at(c_a, -1), deathstring);
EXPECT_DEATH(gsl::at(c_a, 4), deathstring);
}
TEST_CASE("InitializerList")
TEST(at_tests, InitializerList)
{
std::initializer_list<int> a = {1, 2, 3, 4};
const std::initializer_list<int> a = {1, 2, 3, 4};
for (int i = 0; i < 4; ++i) {
CHECK(gsl::at(a, i) == i + 1);
CHECK(gsl::at({1, 2, 3, 4}, i) == i + 1);
EXPECT_TRUE(gsl::at(a, i) == i + 1);
EXPECT_TRUE(gsl::at({1, 2, 3, 4}, i) == i + 1);
}
CHECK_THROWS_AS(gsl::at(a, -1), fail_fast);
CHECK_THROWS_AS(gsl::at(a, 4), fail_fast);
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, -1), fail_fast);
CHECK_THROWS_AS(gsl::at({1, 2, 3, 4}, 4), fail_fast);
std::set_terminate([] {
std::cerr << "Expected Death. InitializerList";
std::abort();
});
EXPECT_DEATH(gsl::at(a, -1), deathstring);
EXPECT_DEATH(gsl::at(a, 4), deathstring);
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, -1), deathstring);
EXPECT_DEATH(gsl::at({1, 2, 3, 4}, 4), deathstring);
}
#if !defined(_MSC_VER) || defined(__clang__) || _MSC_VER >= 1910
+17 -14
View File
@@ -14,16 +14,12 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, TEST_CASE
#include <gtest/gtest.h>
#include <gsl/multi_span> // for static_bounds, static_bounds_dynamic_range_t
#include <cstddef> // for ptrdiff_t, size_t
namespace gsl {
struct fail_fast;
} // namespace gsl
using namespace std;
using namespace gsl;
@@ -32,7 +28,7 @@ namespace
void use(std::ptrdiff_t&) {}
}
TEST_CASE("basic_bounds")
TEST(bounds_tests, basic_bounds)
{
for (auto point : static_bounds<dynamic_range, 3, 4>{2}) {
for (decltype(point)::size_type j = 0;
@@ -44,7 +40,7 @@ TEST_CASE("basic_bounds")
}
}
TEST_CASE("bounds_basic")
TEST(bounds_tests, bounds_basic)
{
static_bounds<3, 4, 5> b;
const auto a = b.slice();
@@ -53,7 +49,7 @@ TEST_CASE("bounds_basic")
x.slice().slice();
}
TEST_CASE("arrayview_iterator")
TEST(bounds_tests, arrayview_iterator)
{
static_bounds<4, dynamic_range, 2> bounds{3};
@@ -71,7 +67,7 @@ TEST_CASE("arrayview_iterator")
#endif
}
TEST_CASE("bounds_convertible")
TEST(bounds_tests, bounds_convertible)
{
static_bounds<7, 4, 2> b1;
static_bounds<7, dynamic_range, 2> b2 = b1;
@@ -84,16 +80,23 @@ TEST_CASE("bounds_convertible")
static_bounds<7, 4, 2> b4 = b3;
(void) b4;
static_bounds<dynamic_range> b11;
static_bounds<dynamic_range> b5;
static_bounds<34> b6;
std::set_terminate([] {
std::cerr << "Expected Death. bounds_convertible";
std::abort();
});
b5 = static_bounds<20>();
CHECK_THROWS_AS(b6 = b5, fail_fast);
EXPECT_DEATH(b6 = b5, ".*");
b5 = static_bounds<34>();
b6 = b5;
CHECK(b5 == b6);
CHECK(b5.size() == b6.size());
EXPECT_TRUE(b5 == b6);
EXPECT_TRUE(b5.size() == b6.size());
}
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
#endif
+93 -88
View File
@@ -14,7 +14,7 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/gsl_byte> // for to_byte, to_integer, byte, operator&, ope...
@@ -23,102 +23,107 @@ using namespace gsl;
namespace
{
TEST_CASE("construction")
{
{
const byte b = static_cast<byte>(4);
CHECK(static_cast<unsigned char>(b) == 4);
}
{
const byte b = byte(12);
CHECK(static_cast<unsigned char>(b) == 12);
}
{
const byte b = to_byte<12>();
CHECK(static_cast<unsigned char>(b) == 12);
}
{
const unsigned char uc = 12;
const byte b = to_byte(uc);
CHECK(static_cast<unsigned char>(b) == 12);
}
// waiting for C++17 enum class direct initializer support
//{
// byte b { 14 };
// CHECK(static_cast<unsigned char>(b) == 14);
//}
}
TEST_CASE("bitwise_operations")
{
const byte b = to_byte<0xFF>();
byte a = to_byte<0x00>();
CHECK((b | a) == to_byte<0xFF>());
CHECK(a == to_byte<0x00>());
a |= b;
CHECK(a == to_byte<0xFF>());
a = to_byte<0x01>();
CHECK((b & a) == to_byte<0x01>());
a &= b;
CHECK(a == to_byte<0x01>());
CHECK((b ^ a) == to_byte<0xFE>());
CHECK(a == to_byte<0x01>());
a ^= b;
CHECK(a == to_byte<0xFE>());
a = to_byte<0x01>();
CHECK(~a == to_byte<0xFE>());
a = to_byte<0xFF>();
CHECK((a << 4) == to_byte<0xF0>());
CHECK((a >> 4) == to_byte<0x0F>());
a <<= 4;
CHECK(a == to_byte<0xF0>());
a >>= 4;
CHECK(a == to_byte<0x0F>());
}
TEST_CASE("to_integer")
{
const byte b = to_byte<0x12>();
CHECK(0x12 == gsl::to_integer<char>(b));
CHECK(0x12 == gsl::to_integer<short>(b));
CHECK(0x12 == gsl::to_integer<long>(b));
CHECK(0x12 == gsl::to_integer<long long>(b));
CHECK(0x12 == gsl::to_integer<unsigned char>(b));
CHECK(0x12 == gsl::to_integer<unsigned short>(b));
CHECK(0x12 == gsl::to_integer<unsigned long>(b));
CHECK(0x12 == gsl::to_integer<unsigned long long>(b));
// CHECK(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
// CHECK(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
}
int modify_both(gsl::byte & b, int& i)
int modify_both(gsl::byte& b, int& i)
{
i = 10;
b = to_byte<5>();
return i;
}
TEST_CASE("aliasing")
TEST(byte_tests, construction)
{
{
const byte b = static_cast<byte>(4);
EXPECT_TRUE(static_cast<unsigned char>(b) == 4);
}
GSL_SUPPRESS(es.49)
{
const byte b = byte(12);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const byte b = to_byte<12>();
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
{
const unsigned char uc = 12;
const byte b = to_byte(uc);
EXPECT_TRUE(static_cast<unsigned char>(b) == 12);
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
{
const byte b { 14 };
EXPECT_TRUE(static_cast<unsigned char>(b) == 14);
}
#endif
}
TEST(byte_tests, bitwise_operations)
{
const byte b = to_byte<0xFF>();
byte a = to_byte<0x00>();
EXPECT_TRUE((b | a) == to_byte<0xFF>());
EXPECT_TRUE(a == to_byte<0x00>());
a |= b;
EXPECT_TRUE(a == to_byte<0xFF>());
a = to_byte<0x01>();
EXPECT_TRUE((b & a) == to_byte<0x01>());
a &= b;
EXPECT_TRUE(a == to_byte<0x01>());
EXPECT_TRUE((b ^ a) == to_byte<0xFE>());
EXPECT_TRUE(a == to_byte<0x01>());
a ^= b;
EXPECT_TRUE(a == to_byte<0xFE>());
a = to_byte<0x01>();
EXPECT_TRUE(~a == to_byte<0xFE>());
a = to_byte<0xFF>();
EXPECT_TRUE((a << 4) == to_byte<0xF0>());
EXPECT_TRUE((a >> 4) == to_byte<0x0F>());
a <<= 4;
EXPECT_TRUE(a == to_byte<0xF0>());
a >>= 4;
EXPECT_TRUE(a == to_byte<0x0F>());
}
TEST(byte_tests, to_integer)
{
const byte b = to_byte<0x12>();
EXPECT_TRUE(0x12 == gsl::to_integer<char>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<short>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<long long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned char>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned short>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long>(b));
EXPECT_TRUE(0x12 == gsl::to_integer<unsigned long long>(b));
// EXPECT_TRUE(0x12 == gsl::to_integer<float>(b)); // expect compile-time error
// EXPECT_TRUE(0x12 == gsl::to_integer<double>(b)); // expect compile-time error
}
TEST(byte_tests, aliasing)
{
int i{0};
const int res = modify_both(reinterpret_cast<byte&>(i), i);
CHECK(res == i);
EXPECT_TRUE(res == i);
}
}
#ifdef CONFIRM_COMPILATION_ERRORS
copy(src_span_static, dst_span_static);
#endif
+682 -517
View File
File diff suppressed because it is too large Load Diff
+9 -14
View File
@@ -14,25 +14,21 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <cstdlib> // for std::exit
#include <gsl/span> // for span
#include <cstdlib> // for std::exit
#include <gsl/span> // for span
int operator_subscript_no_throw()
int operator_subscript_no_throw() noexcept
{
int arr[10];
gsl::span<int> sp { arr };
int arr[10];
const gsl::span<int> sp{arr};
return sp[11];
}
[[noreturn]] void test_terminate() { std::exit(0); }
void test_terminate()
{
std::exit(0);
}
void setup_termination_handler()
void setup_termination_handler() noexcept
{
#if defined(_MSC_VER)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
auto& handler = gsl::details::get_terminate_handler();
handler = &test_terminate;
@@ -44,8 +40,7 @@ void setup_termination_handler()
#endif
}
int main()
int main() noexcept
{
setup_termination_handler();
operator_subscript_no_throw();
-51
View File
@@ -1,51 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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 <cstdlib> // for std::exit
#include <gsl/gsl_util> // for narrow
int narrow_no_throw()
{
long long bigNumber = 0x0fffffffffffffff;
return gsl::narrow<int>(bigNumber);
}
void test_terminate()
{
std::exit(0);
}
void setup_termination_handler()
{
#if defined(_MSC_VER)
auto& handler = gsl::details::get_terminate_handler();
handler = &test_terminate;
#else
std::set_terminate(test_terminate);
#endif
}
int main()
{
setup_termination_handler();
narrow_no_throw();
return -1;
}
+307 -103
View File
@@ -14,7 +14,7 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
@@ -25,12 +25,13 @@
#include <string> // for basic_string, operator==, string, operator<<
#include <typeinfo> // for type_info
namespace gsl {
struct fail_fast;
} // namespace gsl
using namespace gsl;
namespace
{
static constexpr char deathstring[] = "Expected Death";
} //namespace
struct MyBase
{
};
@@ -63,6 +64,7 @@ struct CustomPtr
template <typename T, typename U>
std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) == reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -70,6 +72,7 @@ std::string operator==(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
template <typename T, typename U>
std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) != reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -77,6 +80,7 @@ std::string operator!=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
template <typename T, typename U>
std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) < reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -84,6 +88,7 @@ std::string operator<(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
template <typename T, typename U>
std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) > reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -91,6 +96,7 @@ std::string operator>(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
template <typename T, typename U>
std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) <= reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -98,6 +104,7 @@ std::string operator<=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
template <typename T, typename U>
std::string operator>=(CustomPtr<T> const& lhs, CustomPtr<U> const& rhs)
{
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
return reinterpret_cast<const void*>(lhs.p_) >= reinterpret_cast<const void*>(rhs.p_) ? "true"
: "false";
}
@@ -111,79 +118,149 @@ struct NonCopyableNonMovable
NonCopyableNonMovable& operator=(NonCopyableNonMovable&&) = delete;
};
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper_const(not_null<const int*> p) { return *p == 12; }
TEST_CASE("TestNotNullConstructors")
int* return_pointer() { return nullptr; }
TEST(notnull_tests, TestNotNullConstructors)
{
{
#ifdef CONFIRM_COMPILATION_ERRORS
not_null<int*> p = nullptr; // yay...does not compile!
not_null<std::vector<char>*> p = 0; // yay...does not compile!
not_null<int*> p; // yay...does not compile!
std::unique_ptr<int> up = std::make_unique<int>(120);
not_null<int*> p = up;
not_null<int*> p = nullptr; // yay...does not compile!
not_null<std::vector<char>*> p1 = 0; // yay...does not compile!
not_null<int*> p2; // yay...does not compile!
std::unique_ptr<int> up = std::make_unique<int>(120);
not_null<int*> p3 = up;
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
not_null<std::vector<int>> y({1, 2});
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
not_null<std::vector<int>> y({1, 2});
#endif
int i = 12;
auto rp = RefCounted<int>(&i);
not_null<int*> p(rp);
CHECK(p.get() == &i);
}
not_null<std::shared_ptr<int>> x(
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
std::set_terminate([] {
std::cerr << "Expected Death. TestNotNullConstructors";
std::abort();
});
{
// from shared pointer
int i = 12;
auto rp = RefCounted<int>(&i);
not_null<int*> p(rp);
EXPECT_TRUE(p.get() == &i);
#ifdef GSL_THROW_ON_CONTRACT_VIOLATION
int* pi = nullptr;
CHECK_THROWS_AS(not_null<decltype(pi)>(pi), fail_fast);
#endif
not_null<std::shared_ptr<int>> x(
std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
int* pi = nullptr;
EXPECT_DEATH((not_null<decltype(pi)>(pi)), deathstring);
}
{
// from pointer to local
int t = 42;
not_null<int*> x = &t;
helper(&t);
helper_const(&t);
EXPECT_TRUE(*x == 42);
}
{
// from raw pointer
// from not_null pointer
int t = 42;
int* p = &t;
not_null<int*> x = p;
helper(p);
helper_const(p);
helper(x);
helper_const(x);
EXPECT_TRUE(*x == 42);
}
{
// from raw const pointer
// from not_null const pointer
int t = 42;
const int* cp = &t;
not_null<const int*> x = cp;
helper_const(cp);
helper_const(x);
EXPECT_TRUE(*x == 42);
}
{
// from not_null const pointer, using auto
int t = 42;
const int* cp = &t;
auto x = not_null<const int*>{cp};
EXPECT_TRUE(*x == 42);
}
{
// from returned pointer
EXPECT_DEATH(helper(return_pointer()), deathstring);
EXPECT_DEATH(helper_const(return_pointer()), deathstring);
}
}
template<typename T>
template <typename T>
void ostream_helper(T v)
{
not_null<T*> p(&v);
{
std::ostringstream os;
std::ostringstream ref;
os << p;
ref << &v;
CHECK(os.str() == ref.str());
os << static_cast<void*>(p);
ref << static_cast<void*>(&v);
EXPECT_TRUE(os.str() == ref.str());
}
{
std::ostringstream os;
std::ostringstream ref;
os << *p;
ref << v;
CHECK(os.str() == ref.str());
EXPECT_TRUE(os.str() == ref.str());
}
}
TEST_CASE("TestNotNullostream")
TEST(notnull_tests, TestNotNullostream)
{
ostream_helper<int>(17);
ostream_helper<float>(21.5f);
ostream_helper<double>(3.4566e-7f);
ostream_helper<double>(3.4566e-7);
ostream_helper<char>('c');
ostream_helper<uint16_t>(0x0123u);
ostream_helper<const char*>("cstring");
ostream_helper<std::string>("string");
}
TEST_CASE("TestNotNullCasting")
TEST(notnull_tests, TestNotNullCasting)
{
MyBase base;
MyDerived derived;
Unrelated unrelated;
not_null<Unrelated*> u = &unrelated;
not_null<Unrelated*> u{&unrelated};
(void) u;
not_null<MyDerived*> p = &derived;
not_null<MyBase*> q = &base;
not_null<MyDerived*> p{&derived};
not_null<MyBase*> q(&base);
q = p; // allowed with heterogeneous copy ctor
CHECK(q == p);
EXPECT_TRUE(q == p);
#ifdef CONFIRM_COMPILATION_ERRORS
q = u; // no viable conversion possible between MyBase* and Unrelated*
@@ -192,21 +269,26 @@ TEST_CASE("TestNotNullCasting")
not_null<Unrelated*> r = p;
not_null<Unrelated*> s = reinterpret_cast<Unrelated*>(p);
#endif
not_null<Unrelated*> t = reinterpret_cast<Unrelated*>(p.get());
CHECK(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
not_null<Unrelated*> t(reinterpret_cast<Unrelated*>(p.get()));
EXPECT_TRUE(reinterpret_cast<void*>(p.get()) == reinterpret_cast<void*>(t.get()));
}
TEST_CASE("TestNotNullAssignment")
TEST(notnull_tests, TestNotNullAssignment)
{
std::set_terminate([] {
std::cerr << "Expected Death. TestNotNullAssignmentd";
std::abort();
});
int i = 12;
not_null<int*> p = &i;
CHECK(helper(p));
not_null<int*> p(&i);
EXPECT_TRUE(helper(p));
int* q = nullptr;
CHECK_THROWS_AS(p = q, fail_fast);
EXPECT_DEATH(p = not_null<int*>(q), deathstring);
}
TEST_CASE("TestNotNullRawPointerComparison")
TEST(notnull_tests, TestNotNullRawPointerComparison)
{
int ints[2] = {42, 43};
int* p1 = &ints[0];
@@ -215,57 +297,56 @@ TEST_CASE("TestNotNullRawPointerComparison")
using NotNull1 = not_null<decltype(p1)>;
using NotNull2 = not_null<decltype(p2)>;
CHECK((NotNull1(p1) == NotNull1(p1)) == true);
CHECK((NotNull1(p1) == NotNull2(p2)) == false);
EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == true);
EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == false);
CHECK((NotNull1(p1) != NotNull1(p1)) == false);
CHECK((NotNull1(p1) != NotNull2(p2)) == true);
EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == false);
EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == true);
CHECK((NotNull1(p1) < NotNull1(p1)) == false);
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == false);
EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
CHECK((NotNull1(p1) > NotNull1(p1)) == false);
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
CHECK((NotNull1(p1) <= NotNull1(p1)) == true);
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == false);
EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == true);
EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
}
TEST_CASE("TestNotNullDereferenceOperator")
TEST(notnull_tests, TestNotNullDereferenceOperator)
{
{
auto sp1 = std::make_shared<NonCopyableNonMovable>();
using NotNullSp1 = not_null<decltype(sp1)>;
CHECK(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
CHECK(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
EXPECT_TRUE(typeid(*sp1) == typeid(*NotNullSp1(sp1)));
EXPECT_TRUE(std::addressof(*NotNullSp1(sp1)) == std::addressof(*sp1));
}
{
int ints[1] = { 42 };
int ints[1] = {42};
CustomPtr<int> p1(&ints[0]);
using NotNull1 = not_null<decltype(p1)>;
CHECK(typeid(*NotNull1(p1)) == typeid(*p1));
CHECK(*NotNull1(p1) == 42);
EXPECT_TRUE(typeid(*NotNull1(p1)) == typeid(*p1));
EXPECT_TRUE(*NotNull1(p1) == 42);
*NotNull1(p1) = 43;
CHECK(ints[0] == 43);
EXPECT_TRUE(ints[0] == 43);
}
{
int v = 42;
gsl::not_null<int*> p(&v);
CHECK(typeid(*p) == typeid(*(&v)));
EXPECT_TRUE(typeid(*p) == typeid(*(&v)));
*p = 43;
CHECK(v == 43);
EXPECT_TRUE(v == 43);
}
}
TEST_CASE("TestNotNullSharedPtrComparison")
TEST(notnull_tests, TestNotNullSharedPtrComparison)
{
auto sp1 = std::make_shared<int>(42);
auto sp2 = std::make_shared<const int>(43);
@@ -273,30 +354,30 @@ TEST_CASE("TestNotNullSharedPtrComparison")
using NotNullSp1 = not_null<decltype(sp1)>;
using NotNullSp2 = not_null<decltype(sp2)>;
CHECK((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp1(sp1)) == true);
EXPECT_TRUE((NotNullSp1(sp1) == NotNullSp2(sp2)) == false);
CHECK((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp1(sp1)) == false);
EXPECT_TRUE((NotNullSp1(sp1) != NotNullSp2(sp2)) == true);
CHECK((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
CHECK((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp1(sp1)) == false);
EXPECT_TRUE((NotNullSp1(sp1) < NotNullSp2(sp2)) == (sp1 < sp2));
EXPECT_TRUE((NotNullSp2(sp2) < NotNullSp1(sp1)) == (sp2 < sp1));
CHECK((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
CHECK((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
CHECK((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp1(sp1)) == false);
EXPECT_TRUE((NotNullSp1(sp1) > NotNullSp2(sp2)) == (sp1 > sp2));
EXPECT_TRUE((NotNullSp2(sp2) > NotNullSp1(sp1)) == (sp2 > sp1));
CHECK((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
CHECK((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp1(sp1)) == true);
EXPECT_TRUE((NotNullSp1(sp1) <= NotNullSp2(sp2)) == (sp1 <= sp2));
EXPECT_TRUE((NotNullSp2(sp2) <= NotNullSp1(sp1)) == (sp2 <= sp1));
CHECK((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
CHECK((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
CHECK((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp1(sp1)) == true);
EXPECT_TRUE((NotNullSp1(sp1) >= NotNullSp2(sp2)) == (sp1 >= sp2));
EXPECT_TRUE((NotNullSp2(sp2) >= NotNullSp1(sp1)) == (sp2 >= sp1));
}
TEST_CASE("TestNotNullCustomPtrComparison")
TEST(notnull_tests, TestNotNullCustomPtrComparison)
{
int ints[2] = {42, 43};
CustomPtr<int> p1(&ints[0]);
@@ -305,27 +386,150 @@ TEST_CASE("TestNotNullCustomPtrComparison")
using NotNull1 = not_null<decltype(p1)>;
using NotNull2 = not_null<decltype(p2)>;
CHECK((NotNull1(p1) == NotNull1(p1)) == "true");
CHECK((NotNull1(p1) == NotNull2(p2)) == "false");
EXPECT_TRUE((NotNull1(p1) == NotNull1(p1)) == "true");
EXPECT_TRUE((NotNull1(p1) == NotNull2(p2)) == "false");
CHECK((NotNull1(p1) != NotNull1(p1)) == "false");
CHECK((NotNull1(p1) != NotNull2(p2)) == "true");
EXPECT_TRUE((NotNull1(p1) != NotNull1(p1)) == "false");
EXPECT_TRUE((NotNull1(p1) != NotNull2(p2)) == "true");
CHECK((NotNull1(p1) < NotNull1(p1)) == "false");
CHECK((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
CHECK((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
EXPECT_TRUE((NotNull1(p1) < NotNull1(p1)) == "false");
EXPECT_TRUE((NotNull1(p1) < NotNull2(p2)) == (p1 < p2));
EXPECT_TRUE((NotNull2(p2) < NotNull1(p1)) == (p2 < p1));
CHECK((NotNull1(p1) > NotNull1(p1)) == "false");
CHECK((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
CHECK((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
EXPECT_TRUE((NotNull1(p1) > NotNull1(p1)) == "false");
EXPECT_TRUE((NotNull1(p1) > NotNull2(p2)) == (p1 > p2));
EXPECT_TRUE((NotNull2(p2) > NotNull1(p1)) == (p2 > p1));
CHECK((NotNull1(p1) <= NotNull1(p1)) == "true");
CHECK((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
CHECK((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
EXPECT_TRUE((NotNull1(p1) <= NotNull1(p1)) == "true");
EXPECT_TRUE((NotNull1(p1) <= NotNull2(p2)) == (p1 <= p2));
EXPECT_TRUE((NotNull2(p2) <= NotNull1(p1)) == (p2 <= p1));
CHECK((NotNull1(p1) >= NotNull1(p1)) == "true");
CHECK((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
CHECK((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
EXPECT_TRUE((NotNull1(p1) >= NotNull1(p1)) == "true");
EXPECT_TRUE((NotNull1(p1) >= NotNull2(p2)) == (p1 >= p2));
EXPECT_TRUE((NotNull2(p2) >= NotNull1(p1)) == (p2 >= p1));
}
static_assert(std::is_nothrow_move_constructible<not_null<void *>>::value, "not_null must be no-throw move constructible");
#if defined(__cplusplus) && (__cplusplus >= 201703L)
TEST(notnull_tests, TestNotNullConstructorTypeDeduction)
{
{
int i = 42;
not_null x{&i};
helper(not_null{&i});
helper_const(not_null{&i});
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
not_null x{p};
helper(not_null{p});
helper_const(not_null{p});
EXPECT_TRUE(*x == 42);
}
std::set_terminate([] {
std::cerr << "Expected Death. TestNotNullConstructorTypeDeduction";
std::abort();
});
{
auto workaround_macro = []() {
int* p1 = nullptr;
const not_null x{p1};
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
auto workaround_macro = []() {
const int* p1 = nullptr;
const not_null x{p1};
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
int* p = nullptr;
EXPECT_DEATH(helper(not_null{p}), deathstring);
EXPECT_DEATH(helper_const(not_null{p}), deathstring);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
not_null x{nullptr};
helper(not_null{nullptr});
helper_const(not_null{nullptr});
}
#endif
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
TEST(notnull_tests, TestMakeNotNull)
{
{
int i = 42;
const auto x = make_not_null(&i);
helper(make_not_null(&i));
helper_const(make_not_null(&i));
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
const auto x = make_not_null(p);
helper(make_not_null(p));
helper_const(make_not_null(p));
EXPECT_TRUE(*x == 42);
}
std::set_terminate([] {
std::cerr << "Expected Death. TestMakeNotNull";
std::abort();
});
{
const auto workaround_macro = []() {
int* p1 = nullptr;
const auto x = make_not_null(p1);
EXPECT_TRUE(*x == 42);
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
const auto workaround_macro = []() {
const int* p1 = nullptr;
const auto x = make_not_null(p1);
EXPECT_TRUE(*x == 42);
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
int* p = nullptr;
EXPECT_DEATH(helper(make_not_null(p)), deathstring);
EXPECT_DEATH(helper_const(make_not_null(p)), deathstring);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
EXPECT_DEATH(make_not_null(nullptr), deathstring);
EXPECT_DEATH(helper(make_not_null(nullptr)), deathstring);
EXPECT_DEATH(helper_const(make_not_null(nullptr)), deathstring);
}
#endif
}
+6 -5
View File
@@ -14,24 +14,25 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/pointers> // for owner
using namespace gsl;
GSL_SUPPRESS(f.23) // NO-FORMAT: attribute
void f(int* i) { *i += 1; }
TEST_CASE("basic_test")
TEST(owner_tests, basic_test)
{
owner<int*> p = new int(120);
CHECK(*p == 120);
EXPECT_TRUE(*p == 120);
f(p);
CHECK(*p == 121);
EXPECT_TRUE(*p == 121);
delete p;
}
TEST_CASE("check_pointer_constraint")
TEST(owner_tests, check_pointer_constraint)
{
#ifdef CONFIRM_COMPILATION_ERRORS
{
File diff suppressed because it is too large Load Diff
+360
View File
@@ -0,0 +1,360 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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 <gtest/gtest.h>
#include <gsl/gsl_util> // for narrow_cast, at
#include <gsl/span_ext> // for operator==, operator!=, make_span
#include <array> // for array
#include <iostream> // for cerr
#include <vector> // for vector
using namespace std;
using namespace gsl;
namespace
{
static constexpr char deathstring[] = "Expected Death";
} // namespace
TEST(span_ext_test, make_span_from_pointer_length_constructor)
{
std::set_terminate([] {
std::cerr << "Expected Death. from_pointer_length_constructor";
std::abort();
});
int arr[4] = {1, 2, 3, 4};
{
auto s = make_span(&arr[0], 2);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
int* p = nullptr;
auto s = make_span(p, narrow_cast<span<int>::size_type>(0));
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
{
int* p = nullptr;
auto workaround_macro = [=]() { make_span(p, 2); };
EXPECT_DEATH(workaround_macro(), deathstring);
}
}
TEST(span_ext_test, make_span_from_pointer_pointer_construction)
{
int arr[4] = {1, 2, 3, 4};
{
auto s = make_span(&arr[0], &arr[2]);
EXPECT_TRUE(s.size() == 2);
EXPECT_TRUE(s.data() == &arr[0]);
EXPECT_TRUE(s[0] == 1);
EXPECT_TRUE(s[1] == 2);
}
{
auto s = make_span(&arr[0], &arr[0]);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == &arr[0]);
}
{
int* p = nullptr;
auto s = make_span(p, p);
EXPECT_TRUE(s.size() == 0);
EXPECT_TRUE(s.data() == nullptr);
}
}
TEST(span_ext_test, make_span_from_array_constructor)
{
int arr[5] = {1, 2, 3, 4, 5};
int arr2d[2][3] = {1, 2, 3, 4, 5, 6};
int arr3d[2][3][2] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
{
const auto s = make_span(arr);
EXPECT_TRUE(s.size() == 5);
EXPECT_TRUE(s.data() == std::addressof(arr[0]));
}
{
const auto s = make_span(std::addressof(arr2d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr2d[0]));
}
{
const auto s = make_span(std::addressof(arr3d[0]), 1);
EXPECT_TRUE(s.size() == 1);
EXPECT_TRUE(s.data() == std::addressof(arr3d[0]));
}
}
TEST(span_ext_test, make_span_from_dynamic_array_constructor)
{
double(*arr)[3][4] = new double[100][3][4];
{
auto s = make_span(&arr[0][0][0], 10);
EXPECT_TRUE(s.size() == 10);
EXPECT_TRUE(s.data() == &arr[0][0][0]);
}
delete[] arr;
}
TEST(span_ext_test, make_span_from_std_array_constructor)
{
std::array<int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
// This test checks for the bug found in gcc 6.1, 6.2, 6.3, 6.4, 6.5 7.1, 7.2, 7.3 - issue #590
{
span<int> s1 = make_span(arr);
static span<int> s2;
s2 = s1;
#if defined(__GNUC__) && __GNUC__ == 6 && (__GNUC_MINOR__ == 4 || __GNUC_MINOR__ == 5) && \
__GNUC_PATCHLEVEL__ == 0 && defined(__OPTIMIZE__)
// Known to be broken in gcc 6.4 and 6.5 with optimizations
// Issue in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83116
EXPECT_TRUE(s1.size() == 4);
EXPECT_TRUE(s2.size() == 0);
#else
EXPECT_TRUE(s1.size() == s2.size());
#endif
}
}
TEST(span_ext_test, make_span_from_const_std_array_constructor)
{
const std::array<int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
}
TEST(span_ext_test, make_span_from_std_array_const_constructor)
{
std::array<const int, 4> arr = {1, 2, 3, 4};
{
auto s = make_span(arr);
EXPECT_TRUE(s.size() == arr.size());
EXPECT_TRUE(s.data() == arr.data());
}
}
TEST(span_ext_test, make_span_from_container_constructor)
{
std::vector<int> v = {1, 2, 3};
const std::vector<int> cv = v;
{
auto s = make_span(v);
EXPECT_TRUE(s.size() == v.size());
EXPECT_TRUE(s.data() == v.data());
auto cs = make_span(cv);
EXPECT_TRUE(cs.size() == cv.size());
EXPECT_TRUE(cs.data() == cv.data());
}
}
TEST(span_test, interop_with_gsl_at)
{
int arr[5] = {1, 2, 3, 4, 5};
span<int> s{arr};
EXPECT_TRUE(at(s, 0) == 1);
EXPECT_TRUE(at(s, 1) == 2);
}
TEST(span_ext_test, iterator_free_functions)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_TRUE((std::is_same<decltype(s.begin()), decltype(begin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.end()), decltype(end(s))>::value));
EXPECT_TRUE((std::is_same<decltype(std::cbegin(s)), decltype(cbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(std::cend(s)), decltype(cend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rbegin()), decltype(rbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(s.rend()), decltype(rend(s))>::value));
EXPECT_TRUE((std::is_same<decltype(std::crbegin(s)), decltype(crbegin(s))>::value));
EXPECT_TRUE((std::is_same<decltype(std::crend(s)), decltype(crend(s))>::value));
EXPECT_TRUE(s.begin() == begin(s));
EXPECT_TRUE(s.end() == end(s));
EXPECT_TRUE(s.rbegin() == rbegin(s));
EXPECT_TRUE(s.rend() == rend(s));
EXPECT_TRUE(s.begin() == cbegin(s));
EXPECT_TRUE(s.end() == cend(s));
EXPECT_TRUE(s.rbegin() == crbegin(s));
EXPECT_TRUE(s.rend() == crend(s));
}
TEST(span_ext_test, ssize_free_function)
{
int a[] = {1, 2, 3, 4};
span<int> s{a};
EXPECT_FALSE((std::is_same<decltype(s.size()), decltype(ssize(s))>::value));
EXPECT_TRUE(s.size() == static_cast<std::size_t>(ssize(s)));
}
TEST(span_ext_test, comparison_operators)
{
{
span<int> s1;
span<int> s2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 != s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1};
span<int> s1 = arr;
span<int> s2 = arr;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {2, 1}; // bigger
span<int> s1;
span<int> s2 = arr;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2};
int arr2[] = {1, 2};
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 == s2);
EXPECT_FALSE(s1 != s2);
EXPECT_FALSE(s1 < s2);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s1 >= s2);
EXPECT_TRUE(s2 == s1);
EXPECT_FALSE(s2 != s1);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s2 <= s1);
EXPECT_FALSE(s2 > s1);
EXPECT_TRUE(s2 >= s1);
}
{
int arr[] = {1, 2, 3};
span<int> s1 = {&arr[0], 2}; // shorter
span<int> s2 = arr; // longer
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
{
int arr1[] = {1, 2}; // smaller
int arr2[] = {2, 1}; // bigger
span<int> s1 = arr1;
span<int> s2 = arr2;
EXPECT_TRUE(s1 != s2);
EXPECT_TRUE(s2 != s1);
EXPECT_FALSE(s1 == s2);
EXPECT_FALSE(s2 == s1);
EXPECT_TRUE(s1 < s2);
EXPECT_FALSE(s2 < s1);
EXPECT_TRUE(s1 <= s2);
EXPECT_FALSE(s2 <= s1);
EXPECT_TRUE(s2 > s1);
EXPECT_FALSE(s1 > s2);
EXPECT_TRUE(s2 >= s1);
EXPECT_FALSE(s1 >= s2);
}
}
+1075 -1295
View File
File diff suppressed because it is too large Load Diff
+190
View File
@@ -0,0 +1,190 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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 <gtest/gtest.h>
#include <gsl/pointers> // for not_null, operator<, operator<=, operator>
namespace gsl
{
struct fail_fast;
} // namespace gsl
using namespace gsl;
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper(not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool helper_const(not_null<const int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool strict_helper(strict_not_null<int*> p) { return *p == 12; }
GSL_SUPPRESS(f.4) // NO-FORMAT: attribute
bool strict_helper_const(strict_not_null<const int*> p) { return *p == 12; }
int* return_pointer() { return nullptr; }
const int* return_pointer_const() { return nullptr; }
TEST(strict_notnull_tests, TestStrictNotNull)
{
{
// raw ptr <-> strict_not_null
int x = 42;
#ifdef CONFIRM_COMPILATION_ERRORS
strict_not_null<int*> snn = &x;
strict_helper(&x);
strict_helper_const(&x);
strict_helper(return_pointer());
strict_helper_const(return_pointer_const());
#endif
const strict_not_null<int*> snn1{&x};
helper(snn1);
helper_const(snn1);
EXPECT_TRUE(*snn1 == 42);
}
{
// strict_not_null -> strict_not_null
int x = 42;
strict_not_null<int*> snn1{&x};
const strict_not_null<int*> snn2{&x};
strict_helper(snn1);
strict_helper_const(snn1);
strict_helper_const(snn2);
EXPECT_TRUE(snn1 == snn2);
}
{
// strict_not_null -> not_null
int x = 42;
strict_not_null<int*> snn{&x};
const not_null<int*> nn1 = snn;
const not_null<int*> nn2{snn};
helper(snn);
helper_const(snn);
EXPECT_TRUE(snn == nn1);
EXPECT_TRUE(snn == nn2);
}
{
// not_null -> strict_not_null
int x = 42;
not_null<int*> nn{&x};
const strict_not_null<int*> snn1{nn};
const strict_not_null<int*> snn2{nn};
strict_helper(nn);
strict_helper_const(nn);
EXPECT_TRUE(snn1 == nn);
EXPECT_TRUE(snn2 == nn);
std::hash<strict_not_null<int*>> hash_snn;
std::hash<not_null<int*>> hash_nn;
EXPECT_TRUE(hash_nn(snn1) == hash_nn(nn));
EXPECT_TRUE(hash_snn(snn1) == hash_nn(nn));
EXPECT_TRUE(hash_nn(snn1) == hash_nn(snn2));
EXPECT_TRUE(hash_snn(snn1) == hash_snn(nn));
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
strict_not_null<int*> p{nullptr};
}
#endif
}
#if defined(__cplusplus) && (__cplusplus >= 201703L)
namespace
{
static constexpr char deathstring[] = "Expected Death";
}
TEST(strict_notnull_tests, TestStrictNotNullConstructorTypeDeduction)
{
std::set_terminate([] {
std::cerr << "Expected Death. TestStrictNotNullConstructorTypeDeduction";
std::abort();
});
{
int i = 42;
strict_not_null x{&i};
helper(strict_not_null{&i});
helper_const(strict_not_null{&i});
EXPECT_TRUE(*x == 42);
}
{
int i = 42;
int* p = &i;
strict_not_null x{p};
helper(strict_not_null{p});
helper_const(strict_not_null{p});
EXPECT_TRUE(*x == 42);
}
{
auto workaround_macro = []() {
int* p1 = nullptr;
const strict_not_null x{p1};
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
auto workaround_macro = []() {
const int* p1 = nullptr;
const strict_not_null x{p1};
};
EXPECT_DEATH(workaround_macro(), deathstring);
}
{
int* p = nullptr;
EXPECT_DEATH(helper(strict_not_null{p}), deathstring);
EXPECT_DEATH(helper_const(strict_not_null{p}), deathstring);
}
#ifdef CONFIRM_COMPILATION_ERRORS
{
strict_not_null x{nullptr};
helper(strict_not_null{nullptr});
helper_const(strict_not_null{nullptr});
}
#endif
}
#endif // #if defined(__cplusplus) && (__cplusplus >= 201703L)
+268 -235
View File
@@ -14,8 +14,7 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, CHECK...
#include <gtest/gtest.h>
#include <gsl/gsl_byte> // for byte
#include <gsl/gsl_util> // for narrow_cast
#include <gsl/multi_span> // for strided_span, index, multi_span, strided_...
@@ -26,24 +25,80 @@
#include <type_traits> // for integral_constant<>::value, is_convertible
#include <vector> // for vector
namespace gsl {
struct fail_fast;
} // namespace gsl
using namespace std;
using namespace gsl;
namespace
{
static constexpr char deathstring[] = "Expected Death";
struct BaseClass
{
};
struct DerivedClass : BaseClass
{
};
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
void iterate_every_other_element(multi_span<int, dynamic_range> av)
{
// pick every other element
auto length = av.size() / 2;
#if defined(_MSC_VER) && _MSC_VER > 1800
auto bounds = strided_bounds<1>({length}, {2});
#else
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
#endif
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
EXPECT_TRUE(strided.size() == length);
EXPECT_TRUE(strided.bounds().index_bounds()[0] == length);
for (auto i = 0; i < strided.size(); ++i) {
EXPECT_TRUE(strided[i] == av[2 * i + 1]);
}
int idx = 0;
for (auto num : strided) {
EXPECT_TRUE(num == av[2 * idx + 1]);
idx++;
}
}
TEST_CASE("span_section_test")
GSL_SUPPRESS(con.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute // TODO: does not work
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{
const int expected[6] = {2, 3, 10, 11, 18, 19};
auto section = av.section({0, 1, 0}, {3, 1, 2});
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k) {
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the EXPECT_TRUE macro
EXPECT_TRUE(section[idx] == expected[2 * i + 2 * j + k]);
}
}
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k)
EXPECT_TRUE(section[i][j][k] == expected[2 * i + 2 * j + k]);
}
int i = 0;
for (const auto num : section) {
EXPECT_TRUE(num == expected[i]);
i++;
}
}
}
TEST(strided_span_tests, span_section_test)
{
int a[30][4][5];
@@ -53,48 +108,54 @@ TEST_CASE("span_section_test")
(void) subsub;
}
TEST_CASE("span_section")
TEST(strided_span_tests, span_section)
{
std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0);
const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
const strided_span<int, 2> av_section_1 = av.section({1, 2}, {3, 4});
CHECK((av_section_1[{0, 0}] == 12));
CHECK((av_section_1[{0, 1}] == 13));
CHECK((av_section_1[{1, 0}] == 22));
CHECK((av_section_1[{2, 3}] == 35));
EXPECT_TRUE(!av_section_1.empty());
EXPECT_TRUE((av_section_1[{0, 0}] == 12));
EXPECT_TRUE((av_section_1[{0, 1}] == 13));
EXPECT_TRUE((av_section_1[{1, 0}] == 22));
EXPECT_TRUE((av_section_1[{2, 3}] == 35));
const strided_span<int, 2> av_section_2 = av_section_1.section({1, 2}, {2, 2});
CHECK((av_section_2[{0, 0}] == 24));
CHECK((av_section_2[{0, 1}] == 25));
CHECK((av_section_2[{1, 0}] == 34));
EXPECT_TRUE(!av_section_2.empty());
EXPECT_TRUE((av_section_2[{0, 0}] == 24));
EXPECT_TRUE((av_section_2[{0, 1}] == 25));
EXPECT_TRUE((av_section_2[{1, 0}] == 34));
}
TEST_CASE("strided_span_constructors")
TEST(strided_span_tests, strided_span_constructors)
{
// Check stride constructor
// EXPECT_TRUE stride constructor
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
const int carr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
strided_span<int, 1> sav1{arr, {{9}, {1}}}; // T -> T
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{9});
CHECK(sav1.bounds().stride() == 1);
CHECK((sav1[0] == 1 && sav1[8] == 9));
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{9});
EXPECT_TRUE(sav1.bounds().stride() == 1);
EXPECT_TRUE(sav1[0] == 1);
EXPECT_TRUE(sav1[8] == 9);
strided_span<const int, 1> sav2{carr, {{4}, {2}}}; // const T -> const T
CHECK(sav2.bounds().index_bounds() == multi_span_index<1>{4});
CHECK(sav2.bounds().strides() == multi_span_index<1>{2});
CHECK((sav2[0] == 1 && sav2[3] == 7));
EXPECT_TRUE(sav2.bounds().index_bounds() == multi_span_index<1>{4});
EXPECT_TRUE(sav2.bounds().strides() == multi_span_index<1>{2});
EXPECT_TRUE(sav2[0] == 1);
EXPECT_TRUE(sav2[3] == 7);
strided_span<int, 2> sav3{arr, {{2, 2}, {6, 2}}}; // T -> const T
CHECK((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
CHECK((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
EXPECT_TRUE((sav3.bounds().index_bounds() == multi_span_index<2>{2, 2}));
EXPECT_TRUE((sav3.bounds().strides() == multi_span_index<2>{6, 2}));
EXPECT_TRUE((sav3[{0, 0}]) == 1);
EXPECT_TRUE((sav3[{0, 1}]) == 3);
EXPECT_TRUE((sav3[{1, 0}]) == 7);
}
// Check multi_span constructor
// EXPECT_TRUE multi_span constructor
{
int arr[] = {1, 2};
@@ -103,11 +164,11 @@ TEST_CASE("strided_span_constructors")
const multi_span<int> src = arr;
strided_span<int, 1> sav{src, {2, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[1] == 2);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
// strided_span<const int, 1> sav_c{ {src}, {2, 1} };
strided_span<const int, 1> sav_c{multi_span<const int>{src},
strided_bounds<1>{2, 1}};
@@ -115,29 +176,29 @@ TEST_CASE("strided_span_constructors")
strided_span<const int, 1> sav_c{multi_span<const int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_c[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<volatile int, 1> sav_v{src, {2, 1}};
#else
strided_span<volatile int, 1> sav_v{multi_span<volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_v[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From const-qualified source
@@ -145,20 +206,20 @@ TEST_CASE("strided_span_constructors")
const multi_span<const int> src{arr};
strided_span<const int, 1> sav_c{src, {2, 1}};
CHECK(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_c.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_c[1] == 2);
EXPECT_TRUE(sav_c.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_c.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_c[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From volatile-qualified source
@@ -166,19 +227,19 @@ TEST_CASE("strided_span_constructors")
const multi_span<volatile int> src{arr};
strided_span<volatile int, 1> sav_v{src, {2, 1}};
CHECK(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_v.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_v[1] == 2);
EXPECT_TRUE(sav_v.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_v.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_v[1] == 2);
#if _MSC_VER > 1800
#if defined(_MSC_VER) && _MSC_VER > 1800
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
#else
strided_span<const volatile int, 1> sav_cv{multi_span<const volatile int>{src},
strided_bounds<1>{2, 1}};
#endif
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
// From cv-qualified source
@@ -186,19 +247,19 @@ TEST_CASE("strided_span_constructors")
const multi_span<const volatile int> src{arr};
strided_span<const volatile int, 1> sav_cv{src, {2, 1}};
CHECK(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav_cv.bounds().strides() == multi_span_index<1>{1});
CHECK(sav_cv[1] == 2);
EXPECT_TRUE(sav_cv.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav_cv.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav_cv[1] == 2);
}
}
// Check const-casting constructor
// EXPECT_TRUE const-casting constructor
{
int arr[2] = {4, 5};
const multi_span<int, 2> av(arr, 2);
multi_span<const int, 2> av2{av};
CHECK(av2[1] == 5);
EXPECT_TRUE(av2[1] == 5);
static_assert(
std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value,
@@ -206,34 +267,35 @@ TEST_CASE("strided_span_constructors")
const strided_span<int, 1> src{arr, {2, 1}};
strided_span<const int, 1> sav{src};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().stride() == 1);
CHECK(sav[1] == 5);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().stride() == 1);
EXPECT_TRUE(sav[1] == 5);
static_assert(
std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value,
"ctor is not implicit!");
}
// Check copy constructor
// EXPECT_TRUE copy constructor
{
int arr1[2] = {3, 4};
const strided_span<int, 1> src1{arr1, {2, 1}};
strided_span<int, 1> sav1{src1};
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav1.bounds().stride() == 1);
CHECK(sav1[0] == 3);
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav1.bounds().stride() == 1);
EXPECT_TRUE(sav1[0] == 3);
int arr2[6] = {1, 2, 3, 4, 5, 6};
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
strided_span<const int, 2> sav2{src2};
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
EXPECT_TRUE((sav2[{0, 0}]) == 1);
EXPECT_TRUE((sav2[{2, 0}]) == 5);
}
// Check const-casting assignment operator
// EXPECT_TRUE const-casting assignment operator
{
int arr1[2] = {1, 2};
int arr2[6] = {3, 4, 5, 6, 7, 8};
@@ -241,37 +303,38 @@ TEST_CASE("strided_span_constructors")
const strided_span<int, 1> src{arr1, {{2}, {1}}};
strided_span<const int, 1> sav{arr2, {{3}, {2}}};
strided_span<const int, 1>& sav_ref = (sav = src);
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav.bounds().strides() == multi_span_index<1>{1});
CHECK(sav[0] == 1);
CHECK(&sav_ref == &sav);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav[0] == 1);
EXPECT_TRUE(&sav_ref == &sav);
}
// Check copy assignment operator
// EXPECT_TRUE copy assignment operator
{
int arr1[2] = {3, 4};
int arr1b[1] = {0};
const strided_span<int, 1> src1{arr1, {2, 1}};
strided_span<int, 1> sav1{arr1b, {1, 1}};
strided_span<int, 1>& sav1_ref = (sav1 = src1);
CHECK(sav1.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav1.bounds().strides() == multi_span_index<1>{1});
CHECK(sav1[0] == 3);
CHECK(&sav1_ref == &sav1);
EXPECT_TRUE(sav1.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav1.bounds().strides() == multi_span_index<1>{1});
EXPECT_TRUE(sav1[0] == 3);
EXPECT_TRUE(&sav1_ref == &sav1);
const int arr2[6] = {1, 2, 3, 4, 5, 6};
const int arr2b[1] = {0};
const strided_span<const int, 2> src2{arr2, {{3, 2}, {2, 1}}};
strided_span<const int, 2> sav2{arr2b, {{1, 1}, {1, 1}}};
strided_span<const int, 2>& sav2_ref = (sav2 = src2);
CHECK((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
CHECK(&sav2_ref == &sav2);
EXPECT_TRUE((sav2.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((sav2.bounds().strides() == multi_span_index<2>{2, 1}));
EXPECT_TRUE((sav2[{0, 0}] == 1));
EXPECT_TRUE((sav2[{2, 0}] == 5));
EXPECT_TRUE(&sav2_ref == &sav2);
}
}
TEST_CASE("strided_span_slice")
TEST(strided_span_tests, strided_span_slice)
{
std::vector<int> data(5 * 10);
std::iota(begin(data), end(data), 0);
@@ -286,18 +349,18 @@ TEST_CASE("strided_span_slice")
{{5, 10}, {10, 1}}};
strided_span<int, 1> sav_sl = sav[2];
CHECK(sav_sl[0] == 20);
CHECK(sav_sl[9] == 29);
EXPECT_TRUE(sav_sl[0] == 20);
EXPECT_TRUE(sav_sl[9] == 29);
strided_span<const int, 1> csav_sl = sav[3];
CHECK(csav_sl[0] == 30);
CHECK(csav_sl[9] == 39);
EXPECT_TRUE(csav_sl[0] == 30);
EXPECT_TRUE(csav_sl[9] == 39);
CHECK(sav[4][0] == 40);
CHECK(sav[4][9] == 49);
EXPECT_TRUE(sav[4][0] == 40);
EXPECT_TRUE(sav[4][9] == 49);
}
TEST_CASE("strided_span_column_major")
TEST(strided_span_tests, strided_span_column_major)
{
// strided_span may be used to accommodate more peculiar
// use cases, such as column-major multidimensional array
@@ -307,118 +370,123 @@ TEST_CASE("strided_span_column_major")
strided_span<int, 2> cm_sav{cm_array, {{5, 3}, {1, 5}}};
// Accessing elements
CHECK((cm_sav[{0, 0}] == 1));
CHECK((cm_sav[{0, 1}] == 2));
CHECK((cm_sav[{1, 0}] == 4));
CHECK((cm_sav[{4, 2}] == 15));
EXPECT_TRUE((cm_sav[{0, 0}] == 1));
EXPECT_TRUE((cm_sav[{0, 1}] == 2));
EXPECT_TRUE((cm_sav[{1, 0}] == 4));
EXPECT_TRUE((cm_sav[{4, 2}] == 15));
// Slice
strided_span<int, 1> cm_sl = cm_sav[3];
CHECK(cm_sl[0] == 10);
CHECK(cm_sl[1] == 11);
CHECK(cm_sl[2] == 12);
EXPECT_TRUE(cm_sl[0] == 10);
EXPECT_TRUE(cm_sl[1] == 11);
EXPECT_TRUE(cm_sl[2] == 12);
// Section
strided_span<int, 2> cm_sec = cm_sav.section({2, 1}, {3, 2});
CHECK((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
CHECK((cm_sec[{0, 0}] == 8));
CHECK((cm_sec[{0, 1}] == 9));
CHECK((cm_sec[{1, 0}] == 11));
CHECK((cm_sec[{2, 1}] == 15));
EXPECT_TRUE((cm_sec.bounds().index_bounds() == multi_span_index<2>{3, 2}));
EXPECT_TRUE((cm_sec[{0, 0}] == 8));
EXPECT_TRUE((cm_sec[{0, 1}] == 9));
EXPECT_TRUE((cm_sec[{1, 0}] == 11));
EXPECT_TRUE((cm_sec[{2, 1}] == 15));
}
TEST_CASE("strided_span_bounds")
TEST(strided_span_tests, strided_span_bounds)
{
int arr[] = {0, 1, 2, 3};
multi_span<int> av(arr);
std::set_terminate([] {
std::cerr << "Expected Death. strided_span_bounds";
std::abort();
});
{
// incorrect sections
CHECK_THROWS_AS(av.section(0, 0)[0], fail_fast);
CHECK_THROWS_AS(av.section(1, 0)[0], fail_fast);
CHECK_THROWS_AS(av.section(1, 1)[1], fail_fast);
EXPECT_DEATH(av.section(0, 0)[0], deathstring);
EXPECT_DEATH(av.section(1, 0)[0], deathstring);
EXPECT_DEATH(av.section(1, 1)[1], deathstring);
CHECK_THROWS_AS(av.section(2, 5), fail_fast);
CHECK_THROWS_AS(av.section(5, 2), fail_fast);
CHECK_THROWS_AS(av.section(5, 0), fail_fast);
CHECK_THROWS_AS(av.section(0, 5), fail_fast);
CHECK_THROWS_AS(av.section(5, 5), fail_fast);
EXPECT_DEATH(av.section(2, 5), deathstring);
EXPECT_DEATH(av.section(5, 2), deathstring);
EXPECT_DEATH(av.section(5, 0), deathstring);
EXPECT_DEATH(av.section(0, 5), deathstring);
EXPECT_DEATH(av.section(5, 5), deathstring);
}
{
// zero stride
strided_span<int, 1> sav{av, {{4}, {}}};
CHECK(sav[0] == 0);
CHECK(sav[3] == 0);
CHECK_THROWS_AS(sav[4], fail_fast);
EXPECT_TRUE(sav[0] == 0);
EXPECT_TRUE(sav[3] == 0);
EXPECT_DEATH(sav[4], deathstring);
}
{
// zero extent
strided_span<int, 1> sav{av, {{}, {1}}};
CHECK_THROWS_AS(sav[0], fail_fast);
EXPECT_DEATH(sav[0], deathstring);
}
{
// zero extent and stride
strided_span<int, 1> sav{av, {{}, {}}};
CHECK_THROWS_AS(sav[0], fail_fast);
EXPECT_DEATH(sav[0], deathstring);
}
{
// strided array ctor with matching strided bounds
strided_span<int, 1> sav{arr, {4, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{4});
CHECK(sav[3] == 3);
CHECK_THROWS_AS(sav[4], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{4});
EXPECT_TRUE(sav[3] == 3);
EXPECT_DEATH(sav[4], deathstring);
}
{
// strided array ctor with smaller strided bounds
strided_span<int, 1> sav{arr, {2, 1}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav[1] == 1);
CHECK_THROWS_AS(sav[2], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav[1] == 1);
EXPECT_DEATH(sav[2], deathstring);
}
{
// strided array ctor with fitting irregular bounds
strided_span<int, 1> sav{arr, {2, 3}};
CHECK(sav.bounds().index_bounds() == multi_span_index<1>{2});
CHECK(sav[0] == 0);
CHECK(sav[1] == 3);
CHECK_THROWS_AS(sav[2], fail_fast);
EXPECT_TRUE(sav.bounds().index_bounds() == multi_span_index<1>{2});
EXPECT_TRUE(sav[0] == 0);
EXPECT_TRUE(sav[1] == 3);
EXPECT_DEATH(sav[2], deathstring);
}
{
// bounds cross data boundaries - from static arrays
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{arr, {5, 5}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 2}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{arr, {3, 3}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{arr, {4, 5}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 1}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{arr, {5, 5}}), deathstring);
}
{
// bounds cross data boundaries - from array view
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av, {5, 5}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{av, {3, 2}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av, {3, 3}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av, {4, 5}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av, {5, 1}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av, {5, 5}}), deathstring);
}
{
// bounds cross data boundaries - from dynamic arrays
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 2}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {3, 3}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {4, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 1}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 4, {5, 5}}), fail_fast);
CHECK_THROWS_AS((strided_span<int, 1>{av.data(), 2, {2, 2}}), fail_fast);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 2}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {3, 3}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {4, 5}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 1}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 4, {5, 5}}), deathstring);
EXPECT_DEATH((strided_span<int, 1>{av.data(), 2, {2, 2}}), deathstring);
}
#ifdef CONFIRM_COMPILATION_ERRORS
@@ -445,11 +513,16 @@ TEST_CASE("strided_span_bounds")
#endif
}
TEST_CASE("strided_span_type_conversion")
TEST(strided_span_tests, strided_span_type_conversion)
{
int arr[] = {0, 1, 2, 3};
multi_span<int> av(arr);
std::set_terminate([] {
std::cerr << "Expected Death. strided_span_type_conversion";
std::abort();
});
{
strided_span<int, 1> sav{av.data(), av.size(), {av.size() / 2, 2}};
#ifdef CONFIRM_COMPILATION_ERRORS
@@ -470,10 +543,10 @@ TEST_CASE("strided_span_type_conversion")
strided_bounds<2> bounds{{2, bytes.size() / 4}, {bytes.size() / 2, 1}};
strided_span<const byte, 2> sav2{bytes.data(), bytes.size(), bounds};
strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
CHECK(sav3[0][0] == 0);
CHECK(sav3[1][0] == 2);
CHECK_THROWS_AS(sav3[1][1], fail_fast);
CHECK_THROWS_AS(sav3[0][1], fail_fast);
EXPECT_TRUE(sav3[0][0] == 0);
EXPECT_TRUE(sav3[1][0] == 2);
EXPECT_DEATH(sav3[1][1], deathstring);
EXPECT_DEATH(sav3[0][1], deathstring);
}
// retype strided array with regular strides - from multi_span
@@ -483,10 +556,10 @@ TEST_CASE("strided_span_type_conversion")
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
CHECK(sav3[0][0] == 0);
CHECK(sav3[1][0] == 2);
CHECK_THROWS_AS(sav3[1][1], fail_fast);
CHECK_THROWS_AS(sav3[0][1], fail_fast);
EXPECT_TRUE(sav3[0][0] == 0);
EXPECT_TRUE(sav3[1][0] == 2);
EXPECT_DEATH(sav3[1][1], deathstring);
EXPECT_DEATH(sav3[0][1], deathstring);
}
// retype strided array with not enough elements - last dimension of the array is too small
@@ -495,7 +568,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
// retype strided array with not enough elements - strides are too small
@@ -504,7 +577,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
// retype strided array with not enough elements - last dimension does not divide by the new
@@ -514,7 +587,7 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
// retype strided array with not enough elements - strides does not divide by the new
@@ -524,82 +597,63 @@ TEST_CASE("strided_span_type_conversion")
multi_span<const byte, 2, dynamic_range> bytes2 =
as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
strided_span<const byte, 2> sav2{bytes2, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
// retype strided array with irregular strides - from raw data
{
strided_bounds<1> bounds{bytes.size() / 2, 2};
strided_span<const byte, 1> sav2{bytes.data(), bytes.size(), bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
// retype strided array with irregular strides - from multi_span
{
strided_bounds<1> bounds{bytes.size() / 2, 2};
strided_span<const byte, 1> sav2{bytes, bounds};
CHECK_THROWS_AS(sav2.as_strided_span<int>(), fail_fast);
EXPECT_DEATH(sav2.as_strided_span<int>(), deathstring);
}
}
TEST_CASE("empty_strided_spans")
TEST(strided_span_tests, empty_strided_spans)
{
std::set_terminate([] {
std::cerr << "Expected Death. empty_strided_spans";
std::abort();
});
{
multi_span<int, 0> empty_av(nullptr);
strided_span<int, 1> empty_sav{empty_av, {0, 1}};
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
CHECK_THROWS_AS(empty_sav[0], fail_fast);
CHECK_THROWS_AS(empty_sav.begin()[0], fail_fast);
CHECK_THROWS_AS(empty_sav.cbegin()[0], fail_fast);
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
EXPECT_TRUE(empty_sav.empty());
EXPECT_DEATH(empty_sav[0], deathstring);
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
for (const auto& v : empty_sav) {
(void) v;
CHECK(false);
EXPECT_TRUE(false);
}
}
{
strided_span<int, 1> empty_sav{nullptr, 0, {0, 1}};
CHECK(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
CHECK_THROWS_AS(empty_sav[0], fail_fast);
CHECK_THROWS_AS(empty_sav.begin()[0], fail_fast);
CHECK_THROWS_AS(empty_sav.cbegin()[0], fail_fast);
EXPECT_TRUE(empty_sav.bounds().index_bounds() == multi_span_index<1>{0});
EXPECT_DEATH(empty_sav[0], deathstring);
EXPECT_DEATH(empty_sav.begin()[0], deathstring);
EXPECT_DEATH(empty_sav.cbegin()[0], deathstring);
for (const auto& v : empty_sav) {
(void) v;
CHECK(false);
EXPECT_TRUE(false);
}
}
}
void iterate_every_other_element(multi_span<int, dynamic_range> av)
{
// pick every other element
auto length = av.size() / 2;
#if _MSC_VER > 1800
auto bounds = strided_bounds<1>({length}, {2});
#else
auto bounds = strided_bounds<1>(multi_span_index<1>{length}, multi_span_index<1>{2});
#endif
strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
CHECK(strided.size() == length);
CHECK(strided.bounds().index_bounds()[0] == length);
for (auto i = 0; i < strided.size(); ++i) {
CHECK(strided[i] == av[2 * i + 1]);
}
int idx = 0;
for (auto num : strided) {
CHECK(num == av[2 * idx + 1]);
idx++;
}
}
TEST_CASE("strided_span_section_iteration")
TEST(strided_span_tests, strided_span_section_iteration)
{
int arr[8] = {4, 0, 5, 1, 6, 2, 7, 3};
@@ -616,7 +670,7 @@ TEST_CASE("strided_span_section_iteration")
}
}
TEST_CASE("dynamic_strided_span_section_iteration")
TEST(strided_span_tests, dynamic_strided_span_section_iteration)
{
auto arr = new int[8];
for (int i = 0; i < 4; ++i) {
@@ -630,33 +684,7 @@ TEST_CASE("dynamic_strided_span_section_iteration")
delete[] arr;
}
void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
{
const int expected[6] = {2, 3, 10, 11, 18, 19};
auto section = av.section({0, 1, 0}, {3, 1, 2});
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k) {
auto idx = multi_span_index<3>{i, j, k}; // avoid braces in the CHECK macro
CHECK(section[idx] == expected[2 * i + 2 * j + k]);
}
}
for (auto i = 0; i < section.extent<0>(); ++i) {
for (auto j = 0; j < section.extent<1>(); ++j)
for (auto k = 0; k < section.extent<2>(); ++k)
CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
}
int i = 0;
for (const auto num : section) {
CHECK(num == expected[i]);
i++;
}
}
TEST_CASE("strided_span_section_iteration_3d")
TEST(strided_span_tests, strided_span_section_iteration_3d)
{
int arr[3][4][2]{};
for (auto i = 0; i < 3; ++i) {
@@ -670,7 +698,7 @@ TEST_CASE("strided_span_section_iteration_3d")
}
}
TEST_CASE("dynamic_strided_span_section_iteration_3d")
TEST(strided_span_tests, dynamic_strided_span_section_iteration_3d)
{
const auto height = 12, width = 2;
const auto size = height * width;
@@ -702,8 +730,13 @@ TEST_CASE("dynamic_strided_span_section_iteration_3d")
delete[] arr;
}
TEST_CASE("strided_span_conversion")
TEST(strided_span_tests, strided_span_conversion)
{
std::set_terminate([] {
std::cerr << "Expected Death. strided_span_conversion";
std::abort();
});
// get an multi_span of 'c' values from the list of X's
struct X
@@ -720,10 +753,10 @@ TEST_CASE("strided_span_conversion")
auto d1 = narrow_cast<int>(sizeof(int)) * 12 / d2;
// convert to 4x12 array of bytes
auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2));
auto av = as_multi_span(as_bytes(as_multi_span(&arr[0], 4)), dim(d1), dim(d2));
CHECK(av.bounds().index_bounds()[0] == 4);
CHECK(av.bounds().index_bounds()[1] == 12);
EXPECT_TRUE(av.bounds().index_bounds()[0] == 4);
EXPECT_TRUE(av.bounds().index_bounds()[1] == 12);
// get the last 4 columns
auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2],
@@ -733,8 +766,8 @@ TEST_CASE("strided_span_conversion")
// convert to array 4x1 array of integers
auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
CHECK(cs.bounds().index_bounds()[0] == 4);
CHECK(cs.bounds().index_bounds()[1] == 1);
EXPECT_TRUE(cs.bounds().index_bounds()[0] == 4);
EXPECT_TRUE(cs.bounds().index_bounds()[1] == 1);
// transpose to 1x4 array
strided_bounds<2> reverse_bounds{
@@ -746,12 +779,12 @@ TEST_CASE("strided_span_conversion")
// slice to get a one-dimensional array of c's
strided_span<int, 1> result = transposed[0];
CHECK(result.bounds().index_bounds()[0] == 4);
CHECK_THROWS_AS(result.bounds().index_bounds()[1], fail_fast);
EXPECT_TRUE(result.bounds().index_bounds()[0] == 4);
EXPECT_DEATH(result.bounds().index_bounds()[1], deathstring);
int i = 0;
for (auto& num : result) {
CHECK(num == arr[i].c);
EXPECT_TRUE(num == arr[i].c);
i++;
}
}
File diff suppressed because it is too large Load Diff
-18
View File
@@ -1,18 +0,0 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////////
#define CATCH_CONFIG_MAIN
#include <catch/catch.hpp>
+42 -33
View File
@@ -14,7 +14,7 @@
//
///////////////////////////////////////////////////////////////////////////////
#include <catch/catch.hpp> // for AssertionHandler, StringRef, CHECK, TEST_...
#include <gtest/gtest.h>
#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e...
@@ -23,98 +23,107 @@
#include <limits> // for numeric_limits
#include <stdint.h> // for uint32_t, int32_t
#include <type_traits> // for is_same
#include <cstddef> // for std::ptrdiff_t
using namespace gsl;
TEST_CASE("sanity check for gsl::index typedef")
namespace
{
void f(int& i) { i += 1; }
static int j = 0;
void g() { j += 1; }
}
TEST(utils_tests, sanity_check_for_gsl_index_typedef)
{
static_assert(std::is_same<gsl::index, std::ptrdiff_t>::value,
"gsl::index represents wrong arithmetic type");
}
void f(int& i) { i += 1; }
TEST_CASE("finally_lambda")
TEST(utils_tests, finally_lambda)
{
int i = 0;
{
auto _ = finally([&]() { f(i); });
CHECK(i == 0);
EXPECT_TRUE(i == 0);
}
CHECK(i == 1);
EXPECT_TRUE(i == 1);
}
TEST_CASE("finally_lambda_move")
TEST(utils_tests, finally_lambda_move)
{
int i = 0;
{
auto _1 = finally([&]() { f(i); });
{
auto _2 = std::move(_1);
CHECK(i == 0);
EXPECT_TRUE(i == 0);
}
CHECK(i == 1);
EXPECT_TRUE(i == 1);
{
auto _2 = std::move(_1);
CHECK(i == 1);
EXPECT_TRUE(i == 1);
}
CHECK(i == 1);
EXPECT_TRUE(i == 1);
}
CHECK(i == 1);
EXPECT_TRUE(i == 1);
}
TEST_CASE("finally_function_with_bind")
TEST(utils_tests, finally_function_with_bind)
{
int i = 0;
{
auto _ = finally(std::bind(&f, std::ref(i)));
CHECK(i == 0);
EXPECT_TRUE(i == 0);
}
CHECK(i == 1);
EXPECT_TRUE(i == 1);
}
int j = 0;
void g() { j += 1; }
TEST_CASE("finally_function_ptr")
TEST(utils_tests, finally_function_ptr)
{
j = 0;
{
auto _ = finally(&g);
CHECK(j == 0);
EXPECT_TRUE(j == 0);
}
CHECK(j == 1);
EXPECT_TRUE(j == 1);
}
TEST_CASE("narrow_cast")
TEST(utils_tests, narrow_cast)
{
int n = 120;
char c = narrow_cast<char>(n);
CHECK(c == 120);
EXPECT_TRUE(c == 120);
n = 300;
unsigned char uc = narrow_cast<unsigned char>(n);
CHECK(uc == 44);
EXPECT_TRUE(uc == 44);
}
TEST_CASE("narrow")
TEST(utils_tests, narrow)
{
int n = 120;
const char c = narrow<char>(n);
CHECK(c == 120);
EXPECT_TRUE(c == 120);
n = 300;
CHECK_THROWS_AS(narrow<char>(n), narrowing_error);
EXPECT_THROW(narrow<char>(n), narrowing_error);
const auto int32_max = std::numeric_limits<int32_t>::max();
const auto int32_min = std::numeric_limits<int32_t>::min();
CHECK(narrow<uint32_t>(int32_t(0)) == 0);
CHECK(narrow<uint32_t>(int32_t(1)) == 1);
CHECK(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
EXPECT_TRUE(narrow<uint32_t>(int32_t(0)) == 0);
EXPECT_TRUE(narrow<uint32_t>(int32_t(1)) == 1);
EXPECT_TRUE(narrow<uint32_t>(int32_max) == static_cast<uint32_t>(int32_max));
CHECK_THROWS_AS(narrow<uint32_t>(int32_t(-1)), narrowing_error);
CHECK_THROWS_AS(narrow<uint32_t>(int32_min), narrowing_error);
EXPECT_THROW(narrow<uint32_t>(int32_t(-1)), narrowing_error);
EXPECT_THROW(narrow<uint32_t>(int32_min), narrowing_error);
n = -42;
CHECK_THROWS_AS(narrow<unsigned>(n), narrowing_error);
EXPECT_THROW(narrow<unsigned>(n), narrowing_error);
#if GSL_CONSTEXPR_NARROW
static_assert(narrow<char>(120) == 120, "Fix GSL_CONSTEXPR_NARROW");
#endif
}