Start
This commit is contained in:
parent
95d9dc1557
commit
04e3f0f34f
@ -47,6 +47,7 @@ set(SOURCES
|
||||
system/memory_windows.cpp
|
||||
system/time.cpp
|
||||
system/diskspace.cpp
|
||||
value_type/ValueType.cpp
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${SOURCES})
|
||||
|
4
src/cpp-utils/value_type/ValueType.cpp
Normal file
4
src/cpp-utils/value_type/ValueType.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
//
|
||||
// Created by heinzi on 21/05/18.
|
||||
//
|
||||
|
211
src/cpp-utils/value_type/ValueType.h
Normal file
211
src/cpp-utils/value_type/ValueType.h
Normal file
@ -0,0 +1,211 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_VALUETYPE_H_
|
||||
#define MESSMER_CPPUTILS_VALUETYPE_H_
|
||||
|
||||
#include <functional>
|
||||
#include <cpp-utils/assert/assert.h>
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
// TODO Test
|
||||
template<class Config>
|
||||
class ValueType final {
|
||||
public:
|
||||
using underlying_type = typename Config::underlying_type;
|
||||
|
||||
constexpr explicit ValueType(underlying_type value);
|
||||
|
||||
template<class U = Config>
|
||||
constexpr std::enable_if_t<sizeof(U) && Config::enable_value_access(), underlying_type> value() const {
|
||||
return _value;
|
||||
};
|
||||
|
||||
constexpr ValueType& operator++();
|
||||
constexpr ValueType operator++(int);
|
||||
constexpr ValueType& operator--();
|
||||
constexpr ValueType operator--(int);
|
||||
|
||||
constexpr ValueType& operator+=(ValueType rhs);
|
||||
constexpr ValueType& operator-=(ValueType rhs);
|
||||
constexpr ValueType& operator*=(underlying_type rhs);
|
||||
constexpr ValueType& operator/=(underlying_type rhs);
|
||||
constexpr ValueType& operator%=(underlying_type rhs);
|
||||
|
||||
private:
|
||||
friend struct std::hash<ValueType>;
|
||||
underlying_type _value;
|
||||
};
|
||||
|
||||
/*template<class Config>
|
||||
constexpr ValueType<Config> operator "" _bytes(unsigned long long int value);*/
|
||||
|
||||
template<class Config> constexpr ValueType<Config> operator+(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr ValueType<Config> operator-(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr ValueType<Config> operator*(ValueType<Config> lhs, typename Config::underlying_type rhs);
|
||||
template<class Config> constexpr ValueType<Config> operator*(typename Config::underlying_type lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr ValueType<Config> operator/(ValueType<Config> lhs, typename Config::underlying_type rhs);
|
||||
template<class Config> constexpr typename Config::underlying_type operator/(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr ValueType<Config> operator%(ValueType<Config> lhs, typename Config::underlying_type rhs);
|
||||
template<class Config> constexpr typename Config::underlying_type operator%(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
|
||||
template<class Config> constexpr bool operator==(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr bool operator!=(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr bool operator<(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr bool operator>(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr bool operator<=(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
template<class Config> constexpr bool operator>=(ValueType<Config> lhs, ValueType<Config> rhs);
|
||||
|
||||
|
||||
/*
|
||||
* Implementation follows
|
||||
*/
|
||||
|
||||
/*template<class Config>
|
||||
inline constexpr ValueType<Config> operator "" _bytes(unsigned long long int value) {
|
||||
return ValueType<Config>(value);
|
||||
}*/
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>::ValueType(typename Config::underlying_type value)
|
||||
: _value(value) {}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator++() {
|
||||
++_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> ValueType<Config>::operator++(int) {
|
||||
ValueType<Config> tmp = *this;
|
||||
++(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator--() {
|
||||
--_value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> ValueType<Config>::operator--(int) {
|
||||
ValueType<Config> tmp = *this;
|
||||
--(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator+=(ValueType<Config> rhs) {
|
||||
_value += rhs._value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator-=(ValueType<Config> rhs) {
|
||||
_value -= rhs._value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator*=(typename Config::underlying_type rhs) {
|
||||
_value *= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator/=(typename Config::underlying_type rhs) {
|
||||
_value /= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config>& ValueType<Config>::operator%=(typename Config::underlying_type rhs) {
|
||||
_value %= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator+(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs += rhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator-(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs -= rhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator*(ValueType<Config> lhs, typename Config::underlying_type rhs) {
|
||||
return lhs *= rhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator*(typename Config::underlying_type lhs, ValueType<Config> rhs) {
|
||||
return rhs * lhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator/(ValueType<Config> lhs, typename Config::underlying_type rhs) {
|
||||
return lhs /= rhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr typename Config::underlying_type operator/(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs.value() / rhs.value();
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr ValueType<Config> operator%(ValueType<Config> lhs, typename Config::underlying_type rhs) {
|
||||
return lhs %= rhs;
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr typename Config::underlying_type operator%(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs.value() % rhs.value();
|
||||
}
|
||||
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator==(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs.value() == rhs.value();
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator!=(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return !operator==(lhs, rhs);
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator<(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs.value() < rhs.value();
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator>(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return lhs.value() > rhs.value();
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator<=(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return !operator>(lhs, rhs);
|
||||
}
|
||||
|
||||
template<class Config>
|
||||
inline constexpr bool operator>=(ValueType<Config> lhs, ValueType<Config> rhs) {
|
||||
return !operator<(lhs, rhs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
template<class Config>
|
||||
struct hash<cpputils::ValueType<Config>> {
|
||||
constexpr hash() = default;
|
||||
constexpr size_t operator()(cpputils::ValueType<Config> v) {
|
||||
return v._value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -50,6 +50,7 @@ set(SOURCES
|
||||
system/TimeTest.cpp
|
||||
system/MemoryTest.cpp
|
||||
system/HomedirTest.cpp
|
||||
value_type/ValueTypeTest.cpp
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
|
30
test/cpp-utils/value_type/ValueTypeTest.cpp
Normal file
30
test/cpp-utils/value_type/ValueTypeTest.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include <cpp-utils/value_type/ValueType.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using cpputils::ValueType;
|
||||
|
||||
class AllEnabledConfig final {
|
||||
using underlying_type = int;
|
||||
static constexpr bool allow_value_access() { return true; }
|
||||
};
|
||||
|
||||
using AllEnabledValueType = ValueType<AllEnabledConfig>;
|
||||
|
||||
template<class T, class Enable = void> struct has_value_access : std::false_type {};
|
||||
template<class T> struct has_value_access<T, std::void_t<T::value()>> : std::true_type {
|
||||
static_assert(std::is_same<typename T::underlying_type, std::result_of_t<T::value()>>::value, "value() method returns wrong type");
|
||||
};
|
||||
|
||||
struct ConfigWithValueAccess final {
|
||||
using underlying_type = int;
|
||||
static constexpr bool allow_value_access() { return true; }
|
||||
};
|
||||
|
||||
struct ConfigWithoutValueAccess final {
|
||||
using underlying_type = int;
|
||||
static constexpr bool allow_value_access() { return false; }
|
||||
};
|
||||
|
||||
static_assert(has_value_access<ValueType<AllEnabledConfig>>::value, "");
|
||||
static_assert(has_value_access<ValueType<ConfigWithValueAccess>>::value, "");
|
||||
static_assert(!has_value_access<ValueType<ConfigWithoutValueAccess>>::value, "");
|
Loading…
Reference in New Issue
Block a user