// =====================================================================================================================
// 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 .
// =====================================================================================================================
///
/// \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
#include
#include
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
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(x))
, second(fennec::forward(y)) {
}
///
/// \brief Pair Implicit Constructor
/// \param arg1 Value to initialize the first element
/// \param arg2 Value to initialize the first element
template
constexpr pair(Arg1T&& arg1, Arg2T&& arg2)
: first(fennec::forward(arg1))
, second(fennec::forward(arg2)) {
}
///
/// \brief Copy Constructor, copies both elements
constexpr pair(const pair& pair)
: first(fennec::copy(pair.first))
, second(fennec::copy(pair.second)) {
}
///
/// \brief Move Constructor, moves both elements
constexpr pair(pair&& pair) noexcept
: first(fennec::move(pair.first))
, second(fennec::move(pair.second)) {
}
///
/// \brief Copy Assignment, copies both elements
constexpr pair& operator=(const pair& pair) {
first = fennec::copy(pair.first);
second = fennec::copy(pair.second);
return *this;
}
///
/// \brief Move Assignment, moves both elements
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 `true` 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 `true` 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 `true` 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 `true` 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 `true` 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 `true` 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);
}
/// @}
};
template
struct hash> : hash, hash {
constexpr size_t operator()(const pair& p) const {
return fennec::pair_hash( // pair the hashes of both elements
hash::operator()(p.first),
hash::operator()(p.second)
);
}
};
}
#endif // FENNEC_CONTAINERS_PAIR_H