mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 16:18:19 -10:00
Add the ability to configure the `less` operator for `SCP_set`, `SCP_map`, and so forth. Add comparison operators to the type-safe `ID` class so that it can be used with these data structures.
70 lines
2.0 KiB
C++
70 lines
2.0 KiB
C++
#pragma once
|
|
|
|
#include <iosfwd>
|
|
|
|
namespace util {
|
|
|
|
/**
|
|
* @brief A generic class for creating type safe handle types
|
|
*
|
|
* This type should be used when a function returns a handle to an internal resource instead of using an int.
|
|
* Example:
|
|
* @code{.cpp}
|
|
* struct gamesnd_id_tag{};
|
|
* typedef util::ID<gamesnd_id_tag, int, -1> gamesnd_id;
|
|
* @endcode
|
|
*
|
|
* The implementation value should be very light-weight since this class is designed to be passed around by-value.
|
|
*
|
|
* @note This class was copied from http://www.ilikebigbits.com/blog/2014/5/6/type-safe-identifiers-in-c
|
|
*
|
|
* @tparam Tag A unique type tag which is used for distinguishing between two types which use the same Impl type
|
|
* @tparam Impl The internal representation of the handle.
|
|
* @tparam default_value The default value of the handle. If the handle has this value it is considered invalid.
|
|
*/
|
|
template<class Tag, class Impl, Impl default_value>
|
|
class ID
|
|
{
|
|
public:
|
|
typedef Tag tag_type;
|
|
typedef Impl impl_type;
|
|
|
|
static constexpr ID invalid() { return ID(); }
|
|
|
|
// Defaults to ID::invalid()
|
|
constexpr ID() : m_val(default_value) { }
|
|
|
|
// Explicit constructor:
|
|
explicit ID(Impl val) : m_val(val) { }
|
|
|
|
inline Impl value() const { return m_val; }
|
|
|
|
friend bool operator==(ID a, ID b) { return a.m_val == b.m_val; }
|
|
friend bool operator!=(ID a, ID b) { return a.m_val != b.m_val; }
|
|
friend bool operator< (ID a, ID b) { return a.m_val < b.m_val; }
|
|
friend bool operator<=(ID a, ID b) { return a.m_val <= b.m_val; }
|
|
friend bool operator> (ID a, ID b) { return a.m_val > b.m_val; }
|
|
friend bool operator>=(ID a, ID b) { return a.m_val >= b.m_val; }
|
|
|
|
friend std::ostream& operator<< (std::ostream& stream, const ID& id) {
|
|
stream << id.value();
|
|
return stream;
|
|
}
|
|
|
|
inline bool isValid() const { return m_val != default_value; }
|
|
|
|
protected:
|
|
Impl m_val;
|
|
};
|
|
|
|
struct ID_Hash
|
|
{
|
|
template <class Tag, class Impl, Impl default_value>
|
|
size_t operator()(const ID<Tag, Impl, default_value> &id) const
|
|
{
|
|
return std::hash<Impl>{}(id.value());
|
|
}
|
|
};
|
|
|
|
}
|