qTox is a chat, voice, video, and file transfer IM client using the encrypted peer-to-peer Tox protocol.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

132 lines
3.8 KiB

/*
Copyright © 2019 by The qTox Project Contributors
This file is part of qTox, a Qt-based graphical interface for Tox.
qTox is libre 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.
qTox 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 qTox. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STRONGTYPE_H
#define STRONGTYPE_H
#include <QHash>
template <typename T>
struct Addable
{
T operator+(T const& other) const { return static_cast<T const&>(*this).get() + other.get(); };
};
template <typename T, typename Underlying>
struct UnderlyingAddable
{
T operator+(Underlying const& other) const
{
return T(static_cast<T const&>(*this).get() + other);
};
};
template <typename T, typename Underlying>
struct UnitlessDifferencable
{
T operator-(Underlying const& other) const
{
return T(static_cast<T const&>(*this).get() - other);
};
Underlying operator-(T const& other) const
{
return static_cast<T const&>(*this).get() - other.get();
}
};
template <typename T, typename>
struct Incrementable
{
T& operator++()
{
auto& underlying = static_cast<T&>(*this).get();
++underlying;
return static_cast<T&>(*this);
}
T operator++(int)
{
auto ret = T(static_cast<T const&>(*this));
++(*this);
return ret;
}
};
template <typename T, typename>
struct EqualityComparible
{
bool operator==(const T& other) const { return static_cast<T const&>(*this).get() == other.get(); };
bool operator!=(const T& other) const
{
return static_cast<T const&>(*this).get() != other.get();
};
};
template <typename T, typename Underlying>
struct Hashable
{
friend uint qHash(const Hashable<T, Underlying>& key, uint seed = 0)
{
return qHash(static_cast<T const&>(*key).get(), seed);
}
};
template <typename T, typename Underlying>
struct Orderable : EqualityComparible<T, Underlying>
{
bool operator<(const T& rhs) const { return static_cast<T const&>(*this).get() < rhs.get(); }
bool operator>(const T& rhs) const { return static_cast<T const&>(*this).get() > rhs.get(); }
bool operator>=(const T& rhs) const { return static_cast<T const&>(*this).get() >= rhs.get(); }
bool operator<=(const T& rhs) const { return static_cast<T const&>(*this).get() <= rhs.get(); }
};
/* This class facilitates creating a named class which wraps underlying POD,
* avoiding implict casts and arithmetic of the underlying data.
* Usage: Declare named type with arbitrary tag, then hook up Qt metatype for use
* in signals/slots. For queued connections, registering the metatype is also
* required before the type is used.
* using ReceiptNum = NamedType<uint32_t, struct ReceiptNumTag>;
* Q_DECLARE_METATYPE(ReceiptNum);
* qRegisterMetaType<ReceiptNum>();
*/
template <typename T, typename Tag, template <typename, typename> class... Properties>
class NamedType : public Properties<NamedType<T, Tag, Properties...>, T>...
{
public:
using UnderlyingType = T;
NamedType() {}
explicit NamedType(T const& value) : value_(value) {}
T& get() { return value_; }
T const& get() const {return value_; }
private:
T value_;
};
template <typename T, typename Tag, template <typename, typename> class... Properties>
uint qHash(const NamedType<T, Tag, Properties...>& key, uint seed = 0)
{
return qHash(key.get(), seed);
}
#endif // STRONGTYPE_H