From 76e37e8c968e62abf597afdd4554714c6d40ef92 Mon Sep 17 00:00:00 2001 From: asynts Date: Sun, 6 Sep 2020 21:13:34 +0200 Subject: [PATCH] AK: Add Array template. --- AK/Array.h | 83 ++++++++++++++++++++++++++++++++++++++++++ AK/Forward.h | 2 +- AK/Tests/TestArray.cpp | 54 +++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 AK/Array.h create mode 100644 AK/Tests/TestArray.cpp diff --git a/AK/Array.h b/AK/Array.h new file mode 100644 index 00000000000..848101aabc0 --- /dev/null +++ b/AK/Array.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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. + */ + +#pragma once + +#include +#include + +namespace AK { + +template +struct Array { + constexpr const T* data() const { return __data; } + constexpr T* data() { return __data; } + + constexpr size_t size() const { return Size; } + + constexpr Span span() const { return { __data, Size }; } + constexpr Span span() { return { __data, Size }; } + + constexpr const T& at(size_t index) const + { + ASSERT(index < size()); + return (*this)[index]; + } + constexpr T& at(size_t index) + { + ASSERT(index < size()); + return (*this)[index]; + } + + constexpr const T& front() const { return at(0); } + constexpr T& front() { return at(0); } + + constexpr const T& back() const { return at(max(1, size()) - 1); } + constexpr T& back() { return at(max(1, size()) - 1); } + + constexpr bool is_empty() const { return size() == 0; } + + constexpr const T& operator[](size_t index) const { return __data[index]; } + constexpr T& operator[](size_t index) { return __data[index]; } + + using ConstIterator = SimpleIterator; + using Iterator = SimpleIterator; + + constexpr ConstIterator begin() const { return ConstIterator::begin(*this); } + constexpr Iterator begin() { return Iterator::begin(*this); } + + constexpr ConstIterator end() const { return ConstIterator::end(*this); } + constexpr Iterator end() { return Iterator::end(*this); } + + constexpr operator Span() const { return span(); } + constexpr operator Span() { return span(); } + + T __data[Size]; +}; + +} + +using AK::Array; diff --git a/AK/Forward.h b/AK/Forward.h index 9d9019cb7e6..d9f392dc9ec 100644 --- a/AK/Forward.h +++ b/AK/Forward.h @@ -61,7 +61,7 @@ class CircularDuplexStream; template class Span; -template +template class Array; template diff --git a/AK/Tests/TestArray.cpp b/AK/Tests/TestArray.cpp new file mode 100644 index 00000000000..4aaf485956c --- /dev/null +++ b/AK/Tests/TestArray.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 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 HOLDER 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. + */ + +#include + +#include + +// FIXME: Use Span as soon as Span has all the constexpr stuff too. +template +static constexpr int constexpr_sum(const Array& array) +{ + int sum = 0; + for (auto value : array) + sum += value; + + return sum; +} + +TEST_CASE(compile_time_contructible) +{ + constexpr Array array = { 0, 1, 2, 3 }; + static_assert(array.size() == 4); +} + +TEST_CASE(compile_time_iterable) +{ + constexpr Array array = { 0, 1, 2, 3, 4, 5, 6, 7 }; + static_assert(constexpr_sum(array) == 28); +} + +TEST_MAIN(Array)