10cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh///////////////////////////////////////////////////////////////////////////////
20cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh//
30cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
40cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh//
50cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// This code is licensed under the MIT License (MIT).
60cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh//
70cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
80cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
90cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh// THE SOFTWARE.
140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh//
150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh///////////////////////////////////////////////////////////////////////////////
160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <UnitTest++/UnitTest++.h>
18222c2d85fd2ab37128f5cf00d5267489ea2a8625Galik#include <gsl/multi_span>
190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <string>
210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <vector>
220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <list>
230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <iostream>
240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <memory>
250cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#include <map>
260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntoshusing namespace std;
280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntoshusing namespace gsl;
290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntoshnamespace
310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh{
320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	struct BaseClass {};
330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	struct DerivedClass : BaseClass {};
340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh}
350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntoshSUITE(strided_span_tests)
370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh{
380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST (span_section_test)
390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		int a[30][4][5];
410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
42a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh		auto av = as_multi_span(a);
430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		auto sub = av.section({15, 0, 0}, gsl::index<3>{2, 2, 2});
440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		auto subsub = sub.section({1, 0, 0}, gsl::index<3>{1, 1, 1});
450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		(void)subsub;
460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(span_section)
490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		std::vector<int> data(5 * 10);
510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		std::iota(begin(data), end(data), 0);
52a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh        const multi_span<int, 5, 10> av = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 2> av_section_1 = av.section({ 1, 2 }, { 3, 4 });
550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_1[{0, 0}] == 12));
560cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_1[{0, 1}] == 13));
570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_1[{1, 0}] == 22));
580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_1[{2, 3}] == 35));
590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 2> av_section_2 = av_section_1.section({ 1, 2 }, { 2,2 });
610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_2[{0, 0}] == 24));
620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_2[{0, 1}] == 25));
630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((av_section_2[{1, 0}] == 34));
640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(strided_span_constructors)
670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Check stride constructor
690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const int carr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
730cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav1{ arr, {{9}, {1}} }; // T -> T
740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().index_bounds() == index<1>{ 9 });
750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().stride() == 1);
760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1[0] == 1 && sav1[8] == 9);
770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
780cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 1> sav2{ carr, {{ 4 }, { 2 }} }; // const T -> const T
800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav2.bounds().index_bounds() == index<1>{ 4 });
810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav2.bounds().strides() == index<1>{2});
820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav2[0] == 1 && sav2[3] == 7);
830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 2> sav3{ arr, {{ 2, 2 },{ 6, 2 }} }; // T -> const T
850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav3.bounds().index_bounds() == index<2>{ 2, 2 }));
860cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav3.bounds().strides() == index<2>{ 6, 2 }));
870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav3[{0, 0}] == 1 && sav3[{0, 1}] == 3 && sav3[{1, 0}] == 7));
880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
9049e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		// Check multi_span constructor
910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr[] = { 1, 2 };
930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// From non-cv-qualified source
950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
9649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				const multi_span<int> src = arr;
970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<int, 1> sav{ src, {2, 1} };
990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
1000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav.bounds().strides() == index<1>{ 1 });
1010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav[1] == 2);
1020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
1040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				//strided_span<const int, 1> sav_c{ {src}, {2, 1} };
10549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
1060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
10749e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<const int, 1> sav_c{ multi_span<const int>{src}, strided_bounds<1>{2, 1} };
1080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
1090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
1100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c.bounds().strides() == index<1>{ 1 });
1110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c[1] == 2);
1120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
1140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<volatile int, 1> sav_v{ src, {2, 1} };
1150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
11649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<volatile int, 1> sav_v{ multi_span<volatile int>{src}, strided_bounds<1>{2, 1} };
1170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
1180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
1190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v.bounds().strides() == index<1>{ 1 });
1200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v[1] == 2);
1210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
1230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
1240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
12549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
1260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
1270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
1280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
1290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv[1] == 2);
1300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
1310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// From const-qualified source
1330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
13449e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				const multi_span<const int> src{ arr };
1350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<const int, 1> sav_c{ src, {2, 1} };
1370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c.bounds().index_bounds() == index<1>{ 2 });
1380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c.bounds().strides() == index<1>{ 1 });
1390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_c[1] == 2);
1400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
1420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
1430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
14449e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
1450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
1460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
1480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
1490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv[1] == 2);
1500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
1510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// From volatile-qualified source
1530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
15449e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				const multi_span<volatile int> src{ arr };
1550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1560cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<volatile int, 1> sav_v{ src, {2, 1} };
1570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v.bounds().index_bounds() == index<1>{ 2 });
1580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v.bounds().strides() == index<1>{ 1 });
1590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_v[1] == 2);
1600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
1620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
1630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
16449e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ multi_span<const volatile int>{src}, strided_bounds<1>{2, 1} };
1650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
1660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
1670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
1680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv[1] == 2);
1690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
1700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// From cv-qualified source
1720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
17349e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh				const multi_span<const volatile int> src{ arr };
1740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				strided_span<const volatile int, 1> sav_cv{ src, {2, 1} };
1760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().index_bounds() == index<1>{ 2 });
1770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv.bounds().strides() == index<1>{ 1 });
1780cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(sav_cv[1] == 2);
1790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
1800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
1810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Check const-casting constructor
1830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
1840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr[2] = { 4, 5 };
1850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
18649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh			const multi_span<int, 2> av(arr, 2);
18749e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh			multi_span<const int, 2> av2{ av };
1880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(av2[1] == 5);
1890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
19049e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh			static_assert(std::is_convertible<const multi_span<int, 2>, multi_span<const int, 2>>::value, "ctor is not implicit!");
1910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<int, 1> src{ arr, {2, 1} };
1930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 1> sav{ src };
1940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
1950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().stride() == 1);
1960cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[1] == 5);
1970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
1980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			static_assert(std::is_convertible<const strided_span<int, 1>, strided_span<const int, 1>>::value, "ctor is not implicit!");
1990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
2000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Check copy constructor
2020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
2030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr1[2] = { 3, 4 };
2040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<int, 1> src1{ arr1, {2, 1} };
2050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav1{ src1 };
2060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2070cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().index_bounds() == index<1>{ 2 });
2080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().stride() == 1);
2090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1[0] == 3);
2100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr2[6] = { 1, 2, 3, 4, 5, 6 };
2120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<const int, 2> src2{ arr2, {{ 3, 2 }, { 2, 1 }} };
2130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 2> sav2{ src2 };
2140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2.bounds().index_bounds() == index<2>{ 3, 2 }));
2150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2.bounds().strides() == index<2>{ 2, 1 }));
2160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
2170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
2180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Check const-casting assignment operator
2200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
2210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr1[2] = { 1, 2 };
2220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr2[6] = { 3, 4, 5, 6, 7, 8 };
2230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<int, 1> src{ arr1, {{2}, {1}} };
2250cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 1> sav{ arr2, {{3}, {2}} };
2260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 1>& sav_ref = (sav = src);
2270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
2280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().strides() == index<1>{ 1 });
2290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[0] == 1);
2300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(&sav_ref == &sav);
2310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
2320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Check copy assignment operator
2340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
2350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr1[2] = { 3, 4 };
2360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			int arr1b[1] = { 0 };
2370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<int, 1> src1{ arr1, {2, 1} };
2380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav1{ arr1b, {1, 1} };
2390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1>& sav1_ref = (sav1 = src1);
2400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().index_bounds() == index<1>{ 2 });
2410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1.bounds().strides() == index<1>{ 1 });
2420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav1[0] == 3);
2430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(&sav1_ref == &sav1);
2440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const int arr2[6] = { 1, 2, 3, 4, 5, 6 };
2460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const int arr2b[1] = { 0 };
2470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			const strided_span<const int, 2> src2{ arr2, {{ 3, 2 },{ 2, 1 }} };
2480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 2> sav2{ arr2b, {{ 1, 1 },{ 1, 1 }} };
2490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 2>& sav2_ref = (sav2 = src2);
2500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2.bounds().index_bounds() == index<2>{ 3, 2 }));
2510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2.bounds().strides() == index<2>{ 2, 1 }));
2520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK((sav2[{0, 0}] == 1 && sav2[{2, 0}] == 5));
2530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(&sav2_ref == &sav2);
2540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
2550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
2560cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(strided_span_slice)
2580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
2590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		std::vector<int> data(5 * 10);
2600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		std::iota(begin(data), end(data), 0);
261a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh        const multi_span<int, 5, 10> src = as_multi_span(multi_span<int>{data}, dim<5>(), dim<10>());
2620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		const strided_span<int, 2> sav{ src, {{5, 10}, {10, 1}} };
2640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#ifdef CONFIRM_COMPILATION_ERRORS
2650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		const strided_span<const int, 2> csav{ {src},{ { 5, 10 },{ 10, 1 } } };
2660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
26749e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		const strided_span<const int, 2> csav{ multi_span<const int, 5, 10>{ src }, { { 5, 10 },{ 10, 1 } } };
2680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 1> sav_sl = sav[2];
2700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(sav_sl[0] == 20);
2710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(sav_sl[9] == 29);
2720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2730cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<const int, 1> csav_sl = sav[3];
2740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(csav_sl[0] == 30);
2750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(csav_sl[9] == 39);
2760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(sav[4][0] == 40);
2780cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(sav[4][9] == 49);
2790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
2800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(strided_span_column_major)
2820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
2830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// strided_span may be used to accomodate more peculiar
2840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// use cases, such as column-major multidimensional array
2850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// (aka. "FORTRAN" layout).
2860cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		int cm_array[3 * 5] = {
2880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			1, 4, 7, 10, 13,
2890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			2, 5, 8, 11, 14,
2900cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			3, 6, 9, 12, 15
2910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		};
2920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 2> cm_sav{ cm_array, {{ 5, 3 },{ 1, 5 }} };
2930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
2940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Accessing elements
2950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sav[{0, 0}] == 1));
2960cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sav[{0, 1}] == 2));
2970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sav[{1, 0}] == 4));
2980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sav[{4, 2}] == 15));
2990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Slice
3010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 1> cm_sl = cm_sav[3];
3020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(cm_sl[0] == 10);
3040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(cm_sl[1] == 11);
3050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK(cm_sl[2] == 12);
3060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3070cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// Section
3080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		strided_span<int, 2> cm_sec = cm_sav.section( { 2, 1 }, { 3, 2 });
3090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sec.bounds().index_bounds() == index<2>{3, 2}));
3110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sec[{0, 0}] == 8));
3120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sec[{0, 1}] == 9));
3130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sec[{1, 0}] == 11));
3140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		CHECK((cm_sec[{2, 1}] == 15));
3150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
3160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(strided_span_bounds)
3180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
3190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		int arr[] = { 0, 1, 2, 3 };
32049e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		multi_span<int> av(arr);
3210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// incorrect sections
3240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3250cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(0, 0)[0], fail_fast);
3260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(1, 0)[0], fail_fast);
3270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(1, 1)[1], fail_fast);
3280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(2, 5), fail_fast);
3300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(5, 2), fail_fast);
3310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(5, 0), fail_fast);
3320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(0, 5), fail_fast);
3330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(av.section(5, 5), fail_fast);
3340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// zero stride
3380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ av,{ { 4 },{} } };
3390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[0] == 0);
3400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[3] == 0);
3410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[4], fail_fast);
3420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// zero extent
3460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ av,{ {},{ 1 } } };
3470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[0], fail_fast);
3480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// zero extent and stride
3520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ av,{ {},{} } };
3530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[0], fail_fast);
3540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3560cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// strided array ctor with matching strided bounds
3580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ arr,{ 4, 1 } };
3590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().index_bounds() == index<1>{ 4 });
3600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[3] == 3);
3610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[4], fail_fast);
3620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// strided array ctor with smaller strided bounds
3660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ arr,{ 2, 1 } };
3670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
3680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[1] == 1);
3690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[2], fail_fast);
3700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3730cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// strided array ctor with fitting irregular bounds
3740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ arr,{ 2, 3 } };
3750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav.bounds().index_bounds() == index<1>{ 2 });
3760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[0] == 0);
3770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav[1] == 3);
3780cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav[2], fail_fast);
3790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// bounds cross data boundaries - from static arrays
3830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { arr, { 3, 2 } }), fail_fast);
3840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { arr, { 3, 3 } }), fail_fast);
3850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { arr, { 4, 5 } }), fail_fast);
3860cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { arr, { 5, 1 } }), fail_fast);
3870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { arr, { 5, 5 } }), fail_fast);
3880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3900cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
3910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// bounds cross data boundaries - from array view
3920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av, { 3, 2 } }), fail_fast);
3930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av, { 3, 3 } }), fail_fast);
3940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av, { 4, 5 } }), fail_fast);
3950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av, { 5, 1 } }), fail_fast);
3960cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av, { 5, 5 } }), fail_fast);
3970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
3980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
3990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			// bounds cross data boundaries - from dynamic arrays
4010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 3, 2 } }), fail_fast);
4020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 3, 3 } }), fail_fast);
4030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 4, 5 } }), fail_fast);
4040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 5, 1 } }), fail_fast);
4050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 4, { 5, 5 } }), fail_fast);
4060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW((strided_span<int, 1> { av.data(), 2, { 2, 2 } }), fail_fast);
4070cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#ifdef CONFIRM_COMPILATION_ERRORS
4100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav0{ av.data(), { 3, 2 } };
4120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav1{ arr, { 1 } };
4130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav2{ arr, { 1,1,1 } };
4140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav3{ av, { 1 } };
4150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav4{ av, { 1,1,1 } };
416a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav5{ av.as_multi_span(dim<2>(), dim<2>()), { 1 } };
417a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav6{ av.as_multi_span(dim<2>(), dim<2>()), { 1,1,1 } };
418a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav7{ av.as_multi_span(dim<2>(), dim<2>()), { { 1,1 },{ 1,1 },{ 1,1 } } };
4190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			index<1> index{ 0, 1 };
4210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav8{ arr,{ 1,{ 1,1 } } };
4220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav9{ arr,{ { 1,1 },{ 1,1 } } };
4230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav10{ av,{ 1,{ 1,1 } } };
4240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav11{ av,{ { 1,1 },{ 1,1 } } };
425a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav12{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1 } } };
426a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav13{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1 },{ 1,1,1 } } };
427a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh			strided_span<int, 2> sav14{ av.as_multi_span(dim<2>(), dim<2>()),{ { 1,1,1 },{ 1 } } };
4280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
4300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
4310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(strided_span_type_conversion)
4330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
4340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		int arr[] = { 0, 1, 2, 3 };
43549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		multi_span<int> av(arr);
4360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ av.data(), av.size(), { av.size() / 2, 2 } };
4390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#ifdef CONFIRM_COMPILATION_ERRORS
4400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
4410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
4420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> sav{ av, { av.size() / 2, 2 } };
4450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#ifdef CONFIRM_COMPILATION_ERRORS
4460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<long, 1> lsav1 = sav.as_strided_span<long, 1>();
4470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
4480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
45049e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		multi_span<const byte, dynamic_range> bytes = as_bytes(av);
4510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with regular strides - from raw data
4530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
4550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes.data(), bytes.size(), bounds };
4560cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const int, 2> sav3 = sav2.as_strided_span<const int>();
4570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav3[0][0] == 0);
4580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav3[1][0] == 2);
4590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav3[1][1], fail_fast);
4600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav3[0][1], fail_fast);
4610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
46349e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		// retype strided array with regular strides - from multi_span
4640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 2, bytes.size() / 4 }, { bytes.size() / 2, 1 } };
466c4817358aa9c5d2b9b64fa959df4bab0369d2470Som			multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
4670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes2, bounds };
4680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 2> sav3 = sav2.as_strided_span<int>();
4690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav3[0][0] == 0);
4700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(sav3[1][0] == 2);
4710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav3[1][1], fail_fast);
4720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav3[0][1], fail_fast);
4730cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with not enough elements - last dimension of the array is too small
4760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 4,2 },{ 4, 1 } };
478c4817358aa9c5d2b9b64fa959df4bab0369d2470Som			multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
4790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes2, bounds };
4800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
4810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with not enough elements - strides are too small
4840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 4,2 },{ 2, 1 } };
486c4817358aa9c5d2b9b64fa959df4bab0369d2470Som			multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
4870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes2, bounds };
4880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
4890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4900cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with not enough elements - last dimension does not divide by the new typesize
4920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
4930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 2,6 },{ 4, 1 } };
494c4817358aa9c5d2b9b64fa959df4bab0369d2470Som			multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
4950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes2, bounds };
4960cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
4970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
4980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
4990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with not enough elements - strides does not divide by the new typesize
5000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
5010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<2> bounds{ { 2, 1 },{ 6, 1 } };
502c4817358aa9c5d2b9b64fa959df4bab0369d2470Som			multi_span<const byte, 2, dynamic_range> bytes2 = as_multi_span(bytes, dim<2>(), dim(bytes.size() / 2));
5030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 2> sav2{ bytes2, bounds };
5040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
5050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
5060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5070cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		// retype strided array with irregular strides - from raw data
5080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
5090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<1> bounds{ bytes.size() / 2, 2 };
5100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 1> sav2{ bytes.data(), bytes.size(), bounds };
5110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
5120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
5130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
51449e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh		// retype strided array with irregular strides - from multi_span
5150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
5160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_bounds<1> bounds{ bytes.size() / 2, 2 };
5170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<const byte, 1> sav2{ bytes, bounds };
5180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(sav2.as_strided_span<int>(), fail_fast);
5190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
5200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
5210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	TEST(empty_strided_spans)
5230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	{
5240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
52549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh			multi_span<int, 0> empty_av(nullptr);
5260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> empty_sav{ empty_av, { 0, 1 } };
5270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
5290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav[0], fail_fast);
5300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav.begin()[0], fail_fast);
5310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
5320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			for (auto& v : empty_sav)
5340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
5350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                (void)v;
5360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(false);
5370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
5380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
5390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		{
5410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			strided_span<int, 1> empty_sav{ nullptr, 0, { 0, 1 } };
5420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK(empty_sav.bounds().index_bounds() == index<1>{ 0 });
5440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav[0], fail_fast);
5450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav.begin()[0], fail_fast);
5460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			CHECK_THROW(empty_sav.cbegin()[0], fail_fast);
5470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			for (auto& v : empty_sav)
5490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			{
5500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                (void)v;
5510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh				CHECK(false);
5520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh			}
5530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh		}
5540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	}
5550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
55649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh    void iterate_every_other_element(multi_span<int, dynamic_range> av)
5570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
5580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // pick every other element
5590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto length = av.size() / 2;
5610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#if _MSC_VER > 1800
5620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto bounds = strided_bounds<1>({length}, {2});
5630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#else
5640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto bounds = strided_bounds<1>(index<1>{ length }, index<1>{ 2 });
5650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh#endif
5660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        strided_span<int, 1> strided(&av.data()[1], av.size() - 1, bounds);
5670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(strided.size() == length);
5690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(strided.bounds().index_bounds()[0] == length);
5700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto i = 0; i < strided.size(); ++i)
5710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
5720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            CHECK(strided[i] == av[2 * i + 1]);
5730cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
5740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int idx = 0;
5760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto num : strided)
5770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
5780cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            CHECK(num == av[2 * idx + 1]);
5790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            idx++;
5800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
5810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
5820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5830cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    TEST(strided_span_section_iteration)
5840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
5850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int arr[8] = {4,0,5,1,6,2,7,3};
5860cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // static bounds
5880cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
58949e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh            multi_span<int, 8> av(arr, 8);
5900cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_every_other_element(av);
5910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
5920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
5930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // dynamic bounds
5940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
59549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh            multi_span<int, dynamic_range> av(arr, 8);
5960cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_every_other_element(av);
5970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
5980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
5990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    TEST(dynamic_strided_span_section_iteration)
6010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
6020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto arr = new int[8];
6030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (int i = 0; i < 4; ++i)
6040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            arr[2 * i] = 4 + i;
6060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            arr[2 * i + 1] = i;
6070cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
609a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh        auto av = as_multi_span(arr, 8);
6100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        iterate_every_other_element(av);
6110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        delete[] arr;
6130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
6140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
61549e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh    void iterate_second_slice(multi_span<int, dynamic_range, dynamic_range, dynamic_range> av)
6160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
6170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int expected[6] = {2,3,10,11,18,19};
6180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto section = av.section({0,1,0}, {3,1,2});
6190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto i = 0; i < section.extent<0>(); ++i)
6210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            for (auto j = 0; j < section.extent<1>(); ++j)
6230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                for (auto k = 0; k < section.extent<2>(); ++k)
6240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                {
6250cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                    auto idx = index<3>{i,j,k}; // avoid braces in the CHECK macro
6260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                    CHECK(section[idx] == expected[2 * i + 2 * j + k]);
6270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                }
6280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto i = 0; i < section.extent<0>(); ++i)
6310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            for (auto j = 0; j < section.extent<1>(); ++j)
6330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                for (auto k = 0; k < section.extent<2>(); ++k)
6340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                    CHECK(section[i][j][k] == expected[2 * i + 2 * j + k]);
6350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int i = 0;
6380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto num : section)
6390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            CHECK(num == expected[i]);
6410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            i++;
6420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
6440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    TEST(strided_span_section_iteration_3d)
6460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
6470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int arr[3][4][2];
6480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto i = 0; i < 3; ++i)
6490cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6500cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            for (auto j = 0; j < 4; ++j)
6510cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                for (auto k = 0; k < 2; ++k)
6520cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                    arr[i][j][k] = 8 * i + 2 * j + k;
6530cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6540cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6550cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
65649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh            multi_span<int, 3, 4, 2> av = arr;
6570cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_second_slice(av);
6580cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6590cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
6600cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6610cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    TEST(dynamic_strided_span_section_iteration_3d)
6620cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
6630cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto height = 12, width = 2;
6640cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto size = height * width;
6650cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6660cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto arr = new int[size];
6670cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto i = 0; i < size; ++i)
6680cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
6690cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            arr[i] = i;
6700cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6710cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6720cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
673a0cf1ecc499b9a5609dd3436c5d83d08a3377f9dNeil MacIntosh            auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim<2>());
6740cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_second_slice(av);
6750cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6760cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6770cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
678c4817358aa9c5d2b9b64fa959df4bab0369d2470Som            auto av = as_multi_span(as_multi_span(arr, 24), dim(3), dim<4>(), dim<2>());
6790cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_second_slice(av);
6800cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6810cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6820cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
683c4817358aa9c5d2b9b64fa959df4bab0369d2470Som            auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim(4), dim<2>());
6840cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_second_slice(av);
6850cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6860cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6870cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
688c4817358aa9c5d2b9b64fa959df4bab0369d2470Som            auto av = as_multi_span(as_multi_span(arr, 24), dim<3>(), dim<4>(), dim(2));
6890cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            iterate_second_slice(av);
6900cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
6910cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        delete[] arr;
6920cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
6930cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6940cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    TEST(strided_span_conversion)
6950cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    {
69649e80625c682fe88baf9e306a784f8be7350e416Neil MacIntosh        // get an multi_span of 'c' values from the list of X's
6970cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
6980cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        struct X { int a; int b; int c; };
6990cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7000cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        X arr[4] = {{0,1,2},{3,4,5},{6,7,8},{9,10,11}};
7010cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7020cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int s = sizeof(int) / sizeof(byte);
7030cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto d2 = 3 * s;
7040cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto d1 = sizeof(int) * 12 / d2;
7050cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7060cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // convert to 4x12 array of bytes
707c4817358aa9c5d2b9b64fa959df4bab0369d2470Som        auto av = as_multi_span(as_bytes(as_multi_span(arr, 4)), dim(d1), dim(d2));
7080cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7090cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(av.bounds().index_bounds()[0] == 4);
7100cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(av.bounds().index_bounds()[1] == 12);
7110cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7120cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // get the last 4 columns
7130cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto section = av.section({0, 2 * s}, {4, s}); // { { arr[0].c[0], arr[0].c[1], arr[0].c[2], arr[0].c[3] } , { arr[1].c[0], ... } , ... }
7140cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7150cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh                                                       // convert to array 4x1 array of integers
7160cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        auto cs = section.as_strided_span<int>(); // { { arr[0].c }, {arr[1].c } , ... }
7170cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7180cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(cs.bounds().index_bounds()[0] == 4);
7190cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(cs.bounds().index_bounds()[1] == 1);
7200cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7210cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // transpose to 1x4 array
7220cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        strided_bounds<2> reverse_bounds{
7230cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            {cs.bounds().index_bounds()[1] , cs.bounds().index_bounds()[0]},
7240cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            {cs.bounds().strides()[1], cs.bounds().strides()[0]}
7250cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        };
7260cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7270cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        strided_span<int, 2> transposed{cs.data(), cs.bounds().total_size(), reverse_bounds};
7280cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7290cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        // slice to get a one-dimensional array of c's
7300cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        strided_span<int, 1> result = transposed[0];
7310cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7320cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK(result.bounds().index_bounds()[0] == 4);
7330cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        CHECK_THROW(result.bounds().index_bounds()[1], fail_fast);
7340cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7350cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        int i = 0;
7360cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        for (auto& num : result)
7370cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        {
7380cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            CHECK(num == arr[i].c);
7390cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh            i++;
7400cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh        }
7410cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7420cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh    }
7430cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh}
7440cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh
7450cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntoshint main(int, const char *[])
7460cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh{
7470cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh	return UnitTest::RunAllTests();
7480cf947db7760bf5756e4cb0d47c72a257ed527c5Neil MacIntosh}
749