Skip to content

Commit

Permalink
Extended template specialization for empty vector/array.
Browse files Browse the repository at this point in the history
  • Loading branch information
adamshapiro0 committed May 4, 2021
1 parent e29a155 commit 216907a
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 7 deletions.
134 changes: 134 additions & 0 deletions include/frozen/bits/basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,83 @@ class cvector {
}
};

// Specialization for a compile-time empty container.
template <class T>
class cvector<T, 0> {
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<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_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 <std::size_t M>
constexpr cvector(T const (&init)[M])
{
static_assert(M == 0, "Cannot initialize empty cvector");
}

constexpr cvector(std::initializer_list<T> 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 T, std::size_t N>
class carray {
T data_ [N] = {}; // zero-initialization for scalar type T, default-initialized otherwise
Expand Down Expand Up @@ -237,6 +314,8 @@ class carray {
data_[i] = val;
}
};

// Specialization for a compile-time empty container.
template <class T>
class carray<T, 0> {

Expand All @@ -256,6 +335,61 @@ class carray<T, 0> {

// Constructors
constexpr carray(void) = default;
constexpr carray(size_type count, const T& value)
{
// static_assert(count == 0, "Cannot initialize empty carray");
}

template <std::size_t M>
constexpr carray(T const (&init)[M])
{
static_assert(M == 0, "Cannot initialize empty carray");
}

template <std::size_t M>
constexpr carray(std::array<T, M> const &init)
{
static_assert(M == 0, "Cannot initialize empty carray");
}

constexpr carray(std::initializer_list<T> 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) {}

};

Expand Down
5 changes: 0 additions & 5 deletions tests/test_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "bench.hpp"
#include "catch.hpp"

/*
TEST_CASE("empty frozen array", "[array]") {
constexpr frozen::array<int, 0> ze_array{};

Expand All @@ -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);

Expand All @@ -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<short, 1> ze_array{1};
Expand Down
2 changes: 0 additions & 2 deletions tests/test_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include "bench.hpp"
#include "catch.hpp"

/*
TEST_CASE("empty frozen vector", "[vector]") {
constexpr frozen::vector<int, 0> ze_vector{};

Expand All @@ -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<short, 1> ze_vector{1};
Expand Down

0 comments on commit 216907a

Please sign in to comment.