summaryrefslogtreecommitdiffstats
path: root/include/frozen/bits/basic_types.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/frozen/bits/basic_types.h')
-rw-r--r--include/frozen/bits/basic_types.h207
1 files changed, 207 insertions, 0 deletions
diff --git a/include/frozen/bits/basic_types.h b/include/frozen/bits/basic_types.h
new file mode 100644
index 0000000..b54a60d
--- /dev/null
+++ b/include/frozen/bits/basic_types.h
@@ -0,0 +1,207 @@
+/*
+ * Frozen
+ * Copyright 2016 QuarksLab
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef FROZEN_LETITGO_BASIC_TYPES_H
+#define FROZEN_LETITGO_BASIC_TYPES_H
+
+#include "frozen/bits/exceptions.h"
+
+#include <array>
+#include <utility>
+#include <iterator>
+#include <string>
+
+namespace frozen {
+
+namespace bits {
+
+// used as a fake argument for frozen::make_set and frozen::make_map in the case of N=0
+struct ignored_arg {};
+
+template <class T, std::size_t N>
+class cvector {
+ T data [N] = {}; // zero-initialization for scalar type T, default-initialized otherwise
+ std::size_t dsize = 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 size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+
+ // Constructors
+ constexpr cvector(void) = default;
+ constexpr cvector(size_type count, const T& value) : dsize(count) {
+ for (std::size_t i = 0; i < N; ++i)
+ data[i] = value;
+ }
+
+ // Iterators
+ constexpr iterator begin() noexcept { return data; }
+ constexpr iterator end() noexcept { return data + dsize; }
+
+ // Capacity
+ constexpr size_type size() const { return dsize; }
+
+ // Element access
+ constexpr reference operator[](std::size_t index) { return data[index]; }
+ constexpr const_reference operator[](std::size_t index) const { return data[index]; }
+
+ constexpr reference back() { return data[dsize - 1]; }
+ constexpr const_reference back() const { return data[dsize - 1]; }
+
+ // Modifiers
+ constexpr void push_back(const T & a) { data[dsize++] = a; }
+ constexpr void push_back(T && a) { data[dsize++] = std::move(a); }
+ constexpr void pop_back() { --dsize; }
+
+ constexpr void clear() { dsize = 0; }
+};
+
+template <class T, std::size_t N>
+class carray {
+ T data_ [N] = {}; // zero-initialization for scalar type T, default-initialized otherwise
+
+ template <std::size_t M, std::size_t... I>
+ constexpr carray(T const (&init)[M], std::index_sequence<I...>)
+ : data_{init[I]...} {}
+ template <class Iter, std::size_t... I>
+ constexpr carray(Iter iter, std::index_sequence<I...>)
+ : data_{((void)I, *iter++)...} {}
+
+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 carray(void) = default;
+ template <std::size_t M>
+ constexpr carray(T const (&init)[M])
+ : carray(init, std::make_index_sequence<N>())
+ {
+ static_assert(M >= N, "Cannot initialize a carray with an smaller array");
+ }
+ template <std::size_t M>
+ constexpr carray(std::array<T, M> const &init)
+ : carray(&init[0], std::make_index_sequence<N>())
+ {
+ static_assert(M >= N, "Cannot initialize a carray with an smaller array");
+ }
+ constexpr carray(std::initializer_list<T> init)
+ : carray(init.begin(), std::make_index_sequence<N>())
+ {
+ // clang & gcc doesn't recognize init.size() as a constexpr
+ // static_assert(init.size() >= N, "Cannot initialize a carray with an smaller initializer list");
+ }
+
+ // Iterators
+ constexpr iterator begin() noexcept { return data_; }
+ constexpr const_iterator begin() const noexcept { return data_; }
+ constexpr const_iterator cbegin() const noexcept { return data_; }
+ constexpr iterator end() noexcept { return data_ + N; }
+ constexpr const_iterator end() const noexcept { return data_ + N; }
+ constexpr const_iterator cend() const noexcept { return data_ + N; }
+
+ constexpr reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
+ constexpr const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
+ constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
+ constexpr reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
+ constexpr const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
+ constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
+
+ // Capacity
+ constexpr size_type size() const { return N; }
+ constexpr size_type max_size() const { return N; }
+
+ // Element access
+ constexpr reference operator[](std::size_t index) { return data_[index]; }
+ constexpr const_reference operator[](std::size_t index) const { return data_[index]; }
+
+ constexpr reference at(std::size_t index) {
+ if (index > N)
+ FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (" + std::to_string(N) + ')'));
+ return data_[index];
+ }
+ constexpr const_reference at(std::size_t index) const {
+ if (index > N)
+ FROZEN_THROW_OR_ABORT(std::out_of_range("Index (" + std::to_string(index) + ") out of bound (" + std::to_string(N) + ')'));
+ return data_[index];
+ }
+
+ constexpr reference front() { return data_[0]; }
+ constexpr const_reference front() const { return data_[0]; }
+
+ constexpr reference back() { return data_[N - 1]; }
+ constexpr const_reference back() const { return data_[N - 1]; }
+
+ constexpr value_type* data() noexcept { return data_; }
+ constexpr const value_type* data() const noexcept { return data_; }
+
+ // Modifiers
+ constexpr void fill(const value_type& val) {
+ for (std::size_t i = 0; i < N; ++i)
+ data_[i] = val;
+ }
+};
+template <class T>
+class carray<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 carray(void) = default;
+
+};
+
+} // namespace bits
+
+} // namespace frozen
+
+#endif