[util] Move enum_bitfields into util
Continuing on the cleaning up of the src/include 'junk drawer', the enum_bitfields.h and its dependency basic_types.h are now in util.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <util/counted.h>
|
||||
#include <util/enum_bitfields.h>
|
||||
|
||||
namespace bootproto {
|
||||
|
||||
@@ -23,6 +24,7 @@ enum class module_flags : uint8_t {
|
||||
/// informational purposes only.
|
||||
no_load = 0x01,
|
||||
};
|
||||
is_bitfield(module_flags);
|
||||
|
||||
struct module
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <util/counted.h>
|
||||
#include <util/enum_bitfields.h>
|
||||
|
||||
namespace bootproto {
|
||||
|
||||
@@ -23,6 +24,7 @@ enum class section_flags : uint32_t {
|
||||
write = 2,
|
||||
read = 4,
|
||||
};
|
||||
is_bitfield(section_flags);
|
||||
|
||||
struct program_section {
|
||||
uintptr_t phys_addr;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include "enum_bitfields.h"
|
||||
#include <util/enum_bitfields.h>
|
||||
|
||||
namespace elf {
|
||||
|
||||
@@ -61,6 +61,7 @@ enum class segment_flags : uint32_t
|
||||
write = 0x02,
|
||||
read = 0x04,
|
||||
};
|
||||
is_bitfield(segment_flags);
|
||||
|
||||
struct program_header
|
||||
{
|
||||
|
||||
56
src/libraries/util/include/util/basic_types.h
Normal file
56
src/libraries/util/include/util/basic_types.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
/// file basic_types.h
|
||||
/// Type properties that would normally come from <type_traits>
|
||||
|
||||
namespace types {
|
||||
|
||||
template <bool B, typename T = void> struct enable_if {};
|
||||
template <typename T> struct enable_if<true, T> { using type = T; };
|
||||
|
||||
template <typename T> struct is_integral { static constexpr bool value = false; };
|
||||
template <> struct is_integral<char> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<unsigned char> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<short> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<unsigned short> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<int> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<unsigned int> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<long> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<unsigned long> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<long long> { static constexpr bool value = true; };
|
||||
template <> struct is_integral<unsigned long long> { static constexpr bool value = true; };
|
||||
|
||||
template <typename E> struct integral { using type = unsigned long long; };
|
||||
template <> struct integral<char> { using type = char; };
|
||||
template <> struct integral<unsigned char> { using type = unsigned char; };
|
||||
template <> struct integral<short> { using type = short; };
|
||||
template <> struct integral<unsigned short> { using type = unsigned short; };
|
||||
template <> struct integral<int> { using type = int; };
|
||||
template <> struct integral<unsigned int> { using type = unsigned int; };
|
||||
template <> struct integral<long> { using type = long; };
|
||||
template <> struct integral<unsigned long> { using type = unsigned long; };
|
||||
template <> struct integral<long long> { using type = long long; };
|
||||
template <> struct integral<unsigned long long> { using type = unsigned long long; };
|
||||
|
||||
template <typename T, T v>
|
||||
struct integral_constant
|
||||
{
|
||||
using value_type = T;
|
||||
using type = integral_constant;
|
||||
static constexpr value_type value = v;
|
||||
constexpr operator value_type() const noexcept { return value; }
|
||||
constexpr value_type operator()() const noexcept { return value; }
|
||||
};
|
||||
|
||||
using true_type = integral_constant<bool, true>;
|
||||
using false_type = integral_constant<bool, false>;
|
||||
|
||||
template <bool B, typename T, typename F> struct conditional { using type = T; };
|
||||
template <typename T, typename F> struct conditional<false, T, F> { using type = F; };
|
||||
|
||||
template<typename...> struct conjunction : true_type {};
|
||||
template<typename B1> struct conjunction<B1> : B1 {};
|
||||
template<typename B1, typename... Bn>
|
||||
struct conjunction<B1, Bn...> : conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
|
||||
|
||||
|
||||
} // namespace types
|
||||
91
src/libraries/util/include/util/enum_bitfields.h
Normal file
91
src/libraries/util/include/util/enum_bitfields.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <util/basic_types.h>
|
||||
|
||||
namespace util {
|
||||
namespace bits {
|
||||
|
||||
template <typename E>
|
||||
constexpr bool is_enum_bitfield(E) { return false; }
|
||||
|
||||
template <typename E>
|
||||
struct enum_or_int {
|
||||
static constexpr bool value =
|
||||
is_enum_bitfield(E{}) || types::is_integral<E>::value;
|
||||
};
|
||||
|
||||
template <typename E, typename F>
|
||||
struct both_enum_or_int {
|
||||
static constexpr bool value =
|
||||
types::conjunction< enum_or_int<E>, enum_or_int<F> >::value;
|
||||
};
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type&
|
||||
operator |= (E &lhs, F rhs)
|
||||
{
|
||||
return lhs = static_cast<E>(
|
||||
static_cast<typename types::integral<E>::type>(lhs) |
|
||||
static_cast<typename types::integral<F>::type>(rhs));
|
||||
}
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type&
|
||||
operator &= (E &lhs, F rhs)
|
||||
{
|
||||
return lhs = static_cast<E>(
|
||||
static_cast<typename types::integral<E>::type>(lhs) &
|
||||
static_cast<typename types::integral<F>::type>(rhs));
|
||||
}
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type&
|
||||
operator ^= (E &lhs, F rhs)
|
||||
{
|
||||
return lhs = static_cast<E>(
|
||||
static_cast<typename types::integral<E>::type>(lhs) ^
|
||||
static_cast<typename types::integral<F>::type>(rhs));
|
||||
}
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type
|
||||
operator & (E lhs, F rhs) { return lhs &= rhs; }
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type
|
||||
operator | (E lhs, F rhs) { return lhs |= rhs; }
|
||||
|
||||
template <typename E, typename F>
|
||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type
|
||||
operator ^ (E lhs, F rhs) { return lhs ^= rhs; }
|
||||
|
||||
template <typename E>
|
||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),E>::type
|
||||
operator ~ (E rhs) { return static_cast<E>(~static_cast<typename types::integral<E>::type>(rhs)); }
|
||||
|
||||
template <typename E>
|
||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),bool>::type
|
||||
operator ! (E rhs) { return static_cast<typename types::integral<E>::type>(rhs) == 0; }
|
||||
|
||||
/// Override logical-and to mean 'rhs contains all bits in lhs'
|
||||
template <typename E>
|
||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),bool>::type
|
||||
operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; }
|
||||
|
||||
/// Generic 'has' for non-marked bitfields
|
||||
template <typename E, typename F>
|
||||
constexpr bool has(E set, F flags)
|
||||
{
|
||||
return
|
||||
(static_cast<typename types::integral<E>::type>(set) &
|
||||
static_cast<typename types::integral<F>::type>(flags)) ==
|
||||
static_cast<typename types::integral<F>::type>(flags);
|
||||
}
|
||||
|
||||
} // namespace bits
|
||||
} // namespace util
|
||||
|
||||
#define is_bitfield(name) \
|
||||
constexpr bool is_enum_bitfield(name) { return true; } \
|
||||
using namespace ::util::bits;
|
||||
|
||||
Reference in New Issue
Block a user