diff --git a/include/camp/array.hpp b/include/camp/array.hpp index e6368e32..9127545f 100644 --- a/include/camp/array.hpp +++ b/include/camp/array.hpp @@ -192,6 +192,134 @@ struct array { value_type elements[N]; }; +template +struct array { + using value_type = T; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = pointer; + using const_iterator = const_pointer; + + constexpr reference at(size_type) + { + throw std::out_of_range{"camp::array::at detected out of range access"}; + } + + constexpr const_reference at(size_type) const + { + throw std::out_of_range{"camp::array::at detected out of range access"}; + } + + CAMP_HOST_DEVICE constexpr reference operator[](size_type) noexcept + { + return *data(); + } + + CAMP_HOST_DEVICE constexpr const_reference operator[]( + size_type) const noexcept + { + return *data(); + } + + reference front() = delete; + const_reference front() const = delete; + reference back() = delete; + const_reference back() const = delete; + + CAMP_HOST_DEVICE constexpr pointer data() noexcept { return nullptr; } + + CAMP_HOST_DEVICE constexpr const_pointer data() const noexcept + { + return nullptr; + } + + CAMP_HOST_DEVICE constexpr iterator begin() noexcept + { + return iterator(data()); + } + + CAMP_HOST_DEVICE constexpr const_iterator begin() const noexcept + { + return const_iterator(data()); + } + + CAMP_HOST_DEVICE constexpr const_iterator cbegin() const noexcept + { + return const_iterator(data()); + } + + CAMP_HOST_DEVICE constexpr iterator end() noexcept + { + return iterator(data()); + } + + CAMP_HOST_DEVICE constexpr const_iterator end() const noexcept + { + return const_iterator(data()); + } + + CAMP_HOST_DEVICE constexpr const_iterator cend() const noexcept + { + return const_iterator(data()); + } + + CAMP_HOST_DEVICE constexpr bool empty() const noexcept { return true; } + + CAMP_HOST_DEVICE constexpr size_type size() const noexcept { return 0; } + + CAMP_HOST_DEVICE constexpr size_type max_size() const noexcept { return 0; } + + CAMP_HOST_DEVICE constexpr void fill(const T&) {} + + CAMP_HOST_DEVICE constexpr void swap(array&) noexcept {} +}; + +template +CAMP_HOST_DEVICE inline constexpr bool operator==(const array&, + const array&) +{ + return true; +} + +template +CAMP_HOST_DEVICE inline constexpr bool operator!=(const array&, + const array&) +{ + return false; +} + +template +CAMP_HOST_DEVICE inline constexpr bool operator<(const array&, + const array&) +{ + return false; +} + +template +CAMP_HOST_DEVICE inline constexpr bool operator<=(const array&, + const array&) +{ + return true; +} + +template +CAMP_HOST_DEVICE inline constexpr bool operator>(const array&, + const array&) +{ + return false; +} + +template +CAMP_HOST_DEVICE inline constexpr bool operator>=(const array&, + const array&) +{ + return true; +} + template CAMP_HOST_DEVICE inline constexpr bool operator==(const array& lhs, const array& rhs) diff --git a/test/array.cpp b/test/array.cpp index 9bf135f9..4c6a9bd0 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -50,6 +50,48 @@ CAMP_TEST_BEGIN(array, copy_assignment) } CAMP_TEST_END(array, copy_assignment) +CAMP_TEST_BEGIN(array, zero_sized_capacity) +{ + camp::array a{}; + const camp::array& c = a; + + return a.empty() && c.empty() && a.size() == 0 && c.size() == 0 + && a.max_size() == 0 && c.max_size() == 0; +} +CAMP_TEST_END(array, zero_sized_capacity) + +CAMP_TEST_BEGIN(array, zero_sized_data) +{ + camp::array a{}; + const camp::array& c = a; + + return a.data() == nullptr && c.data() == nullptr && a.begin() == a.end() + && c.begin() == c.end() && a.cbegin() == a.cend() + && c.cbegin() == c.cend(); +} +CAMP_TEST_END(array, zero_sized_data) + +CAMP_TEST_BEGIN(array, zero_sized_modifiers) +{ + camp::array a{}; + camp::array b = {}; + + a.fill(3); + camp::swap(a, b); + + return a.empty() && b.empty() && a.size() == 0 && b.size() == 0; +} +CAMP_TEST_END(array, zero_sized_modifiers) + +CAMP_TEST_BEGIN(array, zero_sized_comparisons) +{ + camp::array a{}; + camp::array b = {}; + + return a == b && !(a != b) && !(a < b) && a <= b && !(a > b) && a >= b; +} +CAMP_TEST_END(array, zero_sized_comparisons) + // Not portable as currently implemented TEST(host_array, at) { @@ -77,6 +119,15 @@ TEST(host_array, at) EXPECT_TRUE(exception); } +TEST(host_array, zero_sized_at) +{ + camp::array a{}; + const camp::array& b = a; + + EXPECT_THROW(a.at(0), std::out_of_range); + EXPECT_THROW(b.at(0), std::out_of_range); +} + CAMP_TEST_BEGIN(array, subscript) { camp::array a = {1, 8};