From 29717b4fb89548fc24a86b44e63ac5bbc50aec6b Mon Sep 17 00:00:00 2001 From: Adam Shapiro Date: Mon, 3 May 2021 13:02:01 -0400 Subject: [PATCH] Extended template specialization for empty vector/array. --- include/frozen/bits/basic_types.h | 134 ++++++++++++++++++++++++++++++ tests/test_array.cpp | 5 -- tests/test_vector.cpp | 2 - 3 files changed, 134 insertions(+), 7 deletions(-) diff --git a/include/frozen/bits/basic_types.h b/include/frozen/bits/basic_types.h index 8acbedd..b576f01 100644 --- a/include/frozen/bits/basic_types.h +++ b/include/frozen/bits/basic_types.h @@ -141,6 +141,83 @@ class cvector { } }; +// Specialization for a compile-time empty container. +template +class cvector { +public: + // Container typdefs + using value_type = 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; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + // Constructors + constexpr cvector(void) = default; + constexpr cvector(size_type count, const T& value) + { + // static_assert(count == 0, "Cannot initialize empty cvector"); + } + + template + constexpr cvector(T const (&init)[M]) + { + static_assert(M == 0, "Cannot initialize empty cvector"); + } + + constexpr cvector(std::initializer_list init) + { + static_assert(init.size() == 0, "Cannot initialize empty cvector"); + } + + // Iterators + constexpr iterator begin() noexcept { return nullptr; } + constexpr const_iterator begin() const noexcept { return nullptr; } + constexpr const_iterator cbegin() const noexcept { return nullptr; } + constexpr iterator end() noexcept { return nullptr; } + constexpr const_iterator end() const noexcept { return nullptr; } + constexpr const_iterator cend() const noexcept { return nullptr; } + + constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(); } + constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(); } + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(); } + constexpr reverse_iterator rend() noexcept { return reverse_iterator(); } + constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(); } + constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(); } + + // Capacity + constexpr bool empty() const { return true; } + constexpr size_type size() const { return 0; } + constexpr size_type max_size() const { return 0; } + constexpr size_type capacity() const { return 0; } + + // Element access + constexpr reference at(std::size_t index) { + FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (0)")); + } + constexpr const_reference at(std::size_t index) const { + FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (0)")); + } + + constexpr value_type* data() noexcept { return nullptr; } + constexpr const value_type* data() const noexcept { return nullptr; } + + // Modifiers + constexpr void push_back(const T & a) {} + constexpr void push_back(T && a) {} + constexpr void pop_back() {} + + constexpr void clear() {} + + constexpr void fill(const value_type& val) {} +}; + template class carray { T data_ [N] = {}; // zero-initialization for scalar type T, default-initialized otherwise @@ -237,6 +314,8 @@ class carray { data_[i] = val; } }; + +// Specialization for a compile-time empty container. template class carray { @@ -256,6 +335,61 @@ class carray { // Constructors constexpr carray(void) = default; + constexpr carray(size_type count, const T& value) + { + // static_assert(count == 0, "Cannot initialize empty carray"); + } + + template + constexpr carray(T const (&init)[M]) + { + static_assert(M == 0, "Cannot initialize empty carray"); + } + + template + constexpr carray(std::array const &init) + { + static_assert(M == 0, "Cannot initialize empty carray"); + } + + constexpr carray(std::initializer_list init) + { + static_assert(init.size() == 0, "Cannot initialize empty carray"); + } + + // Iterators + constexpr iterator begin() noexcept { return nullptr; } + constexpr const_iterator begin() const noexcept { return nullptr; } + constexpr const_iterator cbegin() const noexcept { return nullptr; } + constexpr iterator end() noexcept { return nullptr; } + constexpr const_iterator end() const noexcept { return nullptr; } + constexpr const_iterator cend() const noexcept { return nullptr; } + + constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(); } + constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(); } + constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(); } + constexpr reverse_iterator rend() noexcept { return reverse_iterator(); } + constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(); } + constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(); } + + // Capacity + constexpr bool empty() const { return true; } + constexpr size_type size() const { return 0; } + constexpr size_type max_size() const { return 0; } + + // Element access + constexpr reference at(std::size_t index) { + FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (0)")); + } + constexpr const_reference at(std::size_t index) const { + FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (0)")); + } + + constexpr value_type* data() noexcept { return nullptr; } + constexpr const value_type* data() const noexcept { return nullptr; } + + // Modifiers + constexpr void fill(const value_type& val) {} }; diff --git a/tests/test_array.cpp b/tests/test_array.cpp index b643467..7be4583 100644 --- a/tests/test_array.cpp +++ b/tests/test_array.cpp @@ -3,7 +3,6 @@ #include "bench.hpp" #include "catch.hpp" -/* TEST_CASE("empty frozen array", "[array]") { constexpr frozen::array ze_array{}; @@ -16,9 +15,6 @@ TEST_CASE("empty frozen array", "[array]") { constexpr auto max_size = ze_array.max_size(); REQUIRE(max_size == 0); - constexpr auto capacity = ze_array.capacity(); - REQUIRE(capacity == 0); - auto constexpr begin = ze_array.begin(), end = ze_array.end(); REQUIRE(begin == end); @@ -29,7 +25,6 @@ TEST_CASE("empty frozen array", "[array]") { REQUIRE(std::distance(ze_array.rbegin(), ze_array.rend()) == 0); REQUIRE(std::count(ze_array.crbegin(), ze_array.crend(), 3) == 0); } -*/ TEST_CASE("singleton frozen array", "[array]") { constexpr frozen::array ze_array{1}; diff --git a/tests/test_vector.cpp b/tests/test_vector.cpp index 34a881b..3ee1b7a 100644 --- a/tests/test_vector.cpp +++ b/tests/test_vector.cpp @@ -3,7 +3,6 @@ #include "bench.hpp" #include "catch.hpp" -/* TEST_CASE("empty frozen vector", "[vector]") { constexpr frozen::vector ze_vector{}; @@ -29,7 +28,6 @@ TEST_CASE("empty frozen vector", "[vector]") { REQUIRE(std::distance(ze_vector.rbegin(), ze_vector.rend()) == 0); REQUIRE(std::count(ze_vector.crbegin(), ze_vector.crend(), 3) == 0); } -*/ TEST_CASE("singleton frozen vector", "[vector]") { constexpr frozen::vector ze_vector{1};