216 lines
6.7 KiB
C++
216 lines
6.7 KiB
C++
// =====================================================================================================================
|
|
// fennec, a free and open source game engine
|
|
// Copyright © 2025 Medusa Slockbower
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
// =====================================================================================================================
|
|
|
|
///
|
|
/// \file pair.h
|
|
/// \brief A header containing the definition for a container holding a pair of values
|
|
///
|
|
///
|
|
/// \details
|
|
/// \author Medusa Slockbower
|
|
///
|
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
|
///
|
|
///
|
|
|
|
#ifndef FENNEC_CONTAINERS_PAIR_H
|
|
#define FENNEC_CONTAINERS_PAIR_H
|
|
|
|
#include <fennec/containers/tuple.h>
|
|
#include <fennec/lang/hashing.h>
|
|
#include <fennec/lang/utility.h>
|
|
|
|
namespace fennec
|
|
{
|
|
|
|
// TODO: Document
|
|
|
|
///
|
|
/// \brief Struct for holding a pair of values
|
|
/// \tparam TypeT0 The type of the first value
|
|
/// \tparam TypeT1 The type of the second value
|
|
template<typename TypeT0, typename TypeT1>
|
|
struct pair {
|
|
|
|
// Members =============================================================================================================
|
|
|
|
TypeT0 first; ///< The first value in the pair
|
|
TypeT1 second; ///< The second value in the pair
|
|
|
|
// Constructors ========================================================================================================
|
|
|
|
/// \name Constructors & Destructor
|
|
/// @{
|
|
|
|
///
|
|
/// \brief Default Constructor, invokes default constructor for both elements
|
|
constexpr pair() = default;
|
|
|
|
///
|
|
/// \brief Destructor, invokes destructor for both elements
|
|
constexpr ~pair() = default;
|
|
|
|
///
|
|
/// \brief Pair Copy Constructor
|
|
/// \param x Value to copy for the first element
|
|
/// \param y Value to copy for the first element
|
|
constexpr pair(const TypeT0& x, const TypeT1& y)
|
|
: first(x)
|
|
, second(y) {
|
|
}
|
|
|
|
///
|
|
/// \brief Pair Move Constructor
|
|
/// \param x Value to move for the first element
|
|
/// \param y Value to move for the first element
|
|
constexpr pair(TypeT0&& x, TypeT1&& y) noexcept
|
|
: first(fennec::forward<TypeT0>(x))
|
|
, second(fennec::forward<TypeT1>(y)) {
|
|
}
|
|
|
|
///
|
|
/// \brief Pair Implicit Constructor
|
|
/// \param arg1 Value to initialize the first element
|
|
/// \param arg2 Value to initialize the first element
|
|
template<typename Arg1T, typename Arg2T>
|
|
constexpr pair(Arg1T&& arg1, Arg2T&& arg2)
|
|
: first(fennec::forward<Arg1T>(arg1))
|
|
, second(fennec::forward<Arg2T>(arg2)) {
|
|
}
|
|
|
|
///
|
|
/// \brief Copy Constructor, copies both elements
|
|
/// \param pair The pair to copy
|
|
constexpr pair(const pair& pair)
|
|
: first(fennec::copy(pair.first))
|
|
, second(fennec::copy(pair.second)) {
|
|
}
|
|
|
|
///
|
|
/// \brief Move Constructor, moves both elements
|
|
/// \param pair The pair to move
|
|
constexpr pair(pair&& pair) noexcept
|
|
: first(fennec::move(pair.first))
|
|
, second(fennec::move(pair.second)) {
|
|
}
|
|
|
|
///
|
|
/// \brief Copy Assignment, copies both elements
|
|
/// \param pair The pair to copy
|
|
/// \returns A reference to self
|
|
constexpr pair& operator=(const pair& pair) {
|
|
first = fennec::copy(pair.first);
|
|
second = fennec::copy(pair.second);
|
|
return *this;
|
|
}
|
|
|
|
///
|
|
/// \brief Move Assignment, moves both elements
|
|
/// \param pair The pair to move
|
|
/// \returns A reference to self
|
|
constexpr pair& operator=(pair&& pair) {
|
|
first = fennec::move(pair.first);
|
|
second = fennec::move(pair.second);
|
|
return *this;
|
|
}
|
|
|
|
/// @}
|
|
|
|
|
|
// Comparison ==========================================================================================================
|
|
|
|
/// \name Comparison
|
|
/// @{
|
|
|
|
///
|
|
/// \brief Equality Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns \f$true\f$ when both elements of each pair are equal
|
|
constexpr bool operator==(const pair& p) const {
|
|
return first == p.first and second == p.second;
|
|
}
|
|
|
|
///
|
|
/// \brief Inequality Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns \f$true\f$ when either element of each pair are equal
|
|
constexpr bool operator!=(const pair& p) const {
|
|
return first != p.first or second != p.second;
|
|
}
|
|
|
|
///
|
|
/// \brief Less Than Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is less, or they are
|
|
/// equal and the second element is less
|
|
constexpr bool operator<(const pair& p) const {
|
|
return first < p.first or (first == p.first and second < p.second);
|
|
}
|
|
|
|
///
|
|
/// \brief Less Equal Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is less, or they are
|
|
/// equal and the second element is less or equal
|
|
constexpr bool operator<=(const pair& p) const {
|
|
return first < p.first or (first == p.first and second <= p.second);
|
|
}
|
|
|
|
///
|
|
/// \brief Greater Than Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is greater, or they are
|
|
/// equal and the second element is greater
|
|
constexpr bool operator>(const pair& p) const {
|
|
return first > p.first or (first == p.first and second > p.second);
|
|
}
|
|
|
|
///
|
|
/// \brief Greater Equal Operator
|
|
/// \param p Pair to compare with
|
|
/// \returns lexical comparison of both elements, i.e. returns \f$true\f$ when the first element is greater, or they are
|
|
/// equal and the second element is greater or equal
|
|
constexpr bool operator>=(const pair& p) const {
|
|
return first > p.first or (first == p.first and second >= p.second);
|
|
}
|
|
|
|
/// @}
|
|
};
|
|
|
|
///
|
|
/// \brief C++ 11 Hash Specification for `pair<TypeT0, TypeT1>`
|
|
/// \tparam TypeT0 The first type of the pair
|
|
/// \tparam TypeT1 The second type of the pair
|
|
template<typename TypeT0, typename TypeT1>
|
|
struct hash<pair<TypeT0, TypeT1>> : hash<TypeT0>, hash<TypeT1> {
|
|
///
|
|
/// \brief C++ 11 Hash Specification `operator()`
|
|
/// \param p The pair to hash
|
|
/// \returns a pairing of the hashes of both elements of \f$p\f$ using `fennec::pair_hash`
|
|
constexpr size_t operator()(const pair<TypeT0, TypeT1>& p) const {
|
|
return fennec::pair_hash( // pair the hashes of both elements
|
|
hash<TypeT0>::operator()(p.first),
|
|
hash<TypeT1>::operator()(p.second)
|
|
);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif // FENNEC_CONTAINERS_PAIR_H
|