-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9999445
commit dcab018
Showing
7 changed files
with
736 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,357 @@ | ||
// Copyright 2024 Man Group Operations Limited | ||
// | ||
// Licensed 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 mplied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#pragma once | ||
|
||
#include <algorithm> | ||
#include <compare> | ||
|
||
#include "sparrow/array_data.hpp" | ||
#include "sparrow/data_traits.hpp" | ||
|
||
namespace sparrow | ||
{ | ||
template <class T, class L = typename arrow_traits<T>::default_layout> | ||
class typed_array | ||
{ | ||
public: | ||
|
||
using layout_type = L; | ||
|
||
using reference = typename layout_type::reference; | ||
using const_reference = typename layout_type::const_reference; | ||
|
||
using iterator = typename layout_type::iterator; | ||
using const_iterator = typename layout_type::const_iterator; | ||
|
||
using size_type = typename layout_type::size_type; | ||
using const_bitmap_range = typename layout_type::const_bitmap_range; | ||
using const_value_range = typename layout_type::const_value_range; | ||
|
||
explicit typed_array(array_data data); | ||
|
||
// Element access | ||
|
||
///@{ | ||
/* | ||
* @brief Access specified element with bounds checking. | ||
* | ||
* @description Returns a reference to the element at the specified index \p i, with bounds checking. | ||
* If \p i is not within the range of the container, an exception of type std::out_of_range is thrown. | ||
* | ||
* @param i The index of the element to access. | ||
* @return A reference to the element at the specified index. | ||
* @throws std::out_of_range if i is out of range. | ||
*/ | ||
reference at(size_type i); | ||
const_reference at(size_type i) const; | ||
///@} | ||
|
||
///@{ | ||
/* | ||
* @brief Access specified element. | ||
* | ||
* @description Returns a reference to the element at the specified index \p i. No bounds checking is | ||
* performed. | ||
* | ||
* @param i The index of the element to access. | ||
* @return A reference to the element at the specified index. | ||
*/ | ||
reference operator[](size_type); | ||
const_reference operator[](size_type) const; | ||
///@} | ||
|
||
///@{ | ||
/* | ||
* @brief Access the first element. | ||
* | ||
* @description Returns a reference to the first element. | ||
* Calling front on an empty container is undefined. | ||
* | ||
* @return A reference to the first element. | ||
*/ | ||
reference front(); | ||
const_reference front() const; | ||
///@} | ||
|
||
///@{ | ||
/* | ||
* @brief Access the last element. | ||
* | ||
* @description Returns a reference to the last element. | ||
* Calling back on an empty container is undefined. | ||
* | ||
* @return A reference to the last element. | ||
*/ | ||
reference back(); | ||
const_reference back() const; | ||
///@} | ||
|
||
// Iterators | ||
|
||
///@{ | ||
/* | ||
* @brief Returns an iterator to the beginning. | ||
* | ||
* @description Returns an iterator to the first element of the vector. | ||
* If the vector is empty, the returned iterator will be equal to end(). | ||
* | ||
* @return An iterator to the beginning. | ||
*/ | ||
iterator begin(); | ||
const_iterator cbegin() const; | ||
///@} | ||
|
||
///@{ | ||
/** | ||
* @brief Returns an iterator to the end. | ||
* | ||
* @description Returns an iterator to the element following the last element of the vector. | ||
* This element acts as a placeholder; attempting to access it results in undefined behavior. | ||
* | ||
* @return An iterator to the end. | ||
*/ | ||
iterator end(); | ||
const_iterator cend() const; | ||
///@} | ||
|
||
/* | ||
* @brief Returns a range of the bitmap. | ||
* | ||
* @return A range of the bitmap. | ||
*/ | ||
const_bitmap_range bitmap() const; | ||
|
||
/* | ||
* @brief Returns a range of the values. | ||
* | ||
* @return A range of the values. | ||
*/ | ||
const_value_range values() const; | ||
|
||
// Capacity | ||
|
||
/* | ||
* @brief Checks whether the container is empty. | ||
* | ||
* @description Returns whether the container is empty (i.e. whether its size is 0). | ||
* | ||
* @return true if the container is empty, false otherwise. | ||
*/ | ||
bool empty() const; | ||
|
||
/* | ||
* @brief Returns the number of elements. | ||
* | ||
* @description Returns the number of elements in the container, i.e. std::distance(begin(), end()). | ||
* | ||
* @return The number of elements in the container. | ||
*/ | ||
size_type size() const; | ||
|
||
// TODO: Add reserve, capacity, shrink_to_fit | ||
|
||
// Modifiers | ||
|
||
// TODO: Implement insert, erase, push_back, pop_back, clear, resize, swap | ||
|
||
std::strong_ordering operator<=>(const typed_array<T>& other) const; | ||
|
||
bool operator==(const typed_array<T>& other) const; | ||
|
||
bool operator!=(const typed_array<T>& other) const; | ||
|
||
bool operator<(const typed_array<T>& other) const; | ||
|
||
bool operator>(const typed_array<T>& other) const; | ||
|
||
bool operator<=(const typed_array<T>& other) const; | ||
|
||
bool operator>=(const typed_array<T>& other) const; | ||
|
||
private: | ||
|
||
array_data m_data; | ||
layout_type m_layout; | ||
}; | ||
|
||
// Constructors | ||
template <class T, class L> | ||
typed_array<T, L>::typed_array(array_data data) | ||
: m_data(std::move(data)) | ||
, m_layout(m_data) | ||
{ | ||
} | ||
|
||
// Element access | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::at(size_type i) -> reference | ||
{ | ||
if (i >= size()) | ||
{ | ||
throw std::out_of_range( | ||
"typed_array::at: index out of range for array of size " + std::to_string(size()) | ||
+ " at index " + std::to_string(i) | ||
); | ||
} | ||
return m_layout[i]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::at(size_type i) const -> const_reference | ||
{ | ||
if (i >= size()) | ||
{ | ||
throw std::out_of_range( | ||
"typed_array::at: index out of range for array of size " + std::to_string(size()) | ||
+ " at index " + std::to_string(i) | ||
); | ||
} | ||
return m_layout[i]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::operator[](size_type i) -> reference | ||
{ | ||
return m_layout[i]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::operator[](size_type i) const -> const_reference | ||
{ | ||
return m_layout[i]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::front() -> reference | ||
{ | ||
return m_layout[0]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::front() const -> const_reference | ||
{ | ||
return m_layout[0]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::back() -> reference | ||
{ | ||
return m_layout[size() - 1]; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::back() const -> const_reference | ||
{ | ||
return m_layout[size() - 1]; | ||
} | ||
|
||
// Iterators | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::begin() -> iterator | ||
{ | ||
return m_layout.begin(); | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::end() -> iterator | ||
{ | ||
return m_layout.end(); | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::cbegin() const -> const_iterator | ||
{ | ||
return m_layout.cbegin(); | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::cend() const -> const_iterator | ||
{ | ||
return m_layout.cend(); | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::bitmap() const -> const_bitmap_range | ||
{ | ||
return m_layout.bitmap(); | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::values() const -> const_value_range | ||
{ | ||
return m_layout.values(); | ||
} | ||
|
||
// Capacity | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::empty() const | ||
{ | ||
return m_layout.size() == 0; | ||
} | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::size() const -> size_type | ||
{ | ||
return m_layout.size(); | ||
} | ||
|
||
// Comparators | ||
|
||
template <class T, class L> | ||
auto typed_array<T, L>::operator<=>(const typed_array<T>& other) const -> std::strong_ordering | ||
{ | ||
return std::lexicographical_compare_three_way(cbegin(), cend(), other.cbegin(), other.cend()); | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator==(const typed_array<T>& other) const | ||
{ | ||
return std::equal(cbegin(), cend(), other.cbegin(), other.cend()); | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator!=(const typed_array<T>& other) const | ||
{ | ||
return !(*this == other); | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator<(const typed_array<T>& other) const | ||
{ | ||
return std::lexicographical_compare(cbegin(), cend(), other.cbegin(), other.cend()); | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator>(const typed_array<T>& other) const | ||
{ | ||
return other < *this; | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator<=(const typed_array<T>& other) const | ||
{ | ||
return !(other < *this); | ||
} | ||
|
||
template <class T, class L> | ||
bool typed_array<T, L>::operator>=(const typed_array<T>& other) const | ||
{ | ||
return !(*this < other); | ||
} | ||
|
||
} // namespace sparrow |
Oops, something went wrong.