diff --git a/src/include/basic_types.h b/src/include/basic_types.h new file mode 100644 index 0000000..342f574 --- /dev/null +++ b/src/include/basic_types.h @@ -0,0 +1,56 @@ +#pragma once +/// file basic_types.h +/// Type properties that would normally come from + +namespace types { + +template struct enable_if {}; +template struct enable_if { using type = T; }; + +template struct is_integral { static constexpr bool value = false; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; +template <> struct is_integral { static constexpr bool value = true; }; + +template struct integral { using type = unsigned long long; }; +template <> struct integral { using type = char; }; +template <> struct integral { using type = unsigned char; }; +template <> struct integral { using type = short; }; +template <> struct integral { using type = unsigned short; }; +template <> struct integral { using type = int; }; +template <> struct integral { using type = unsigned int; }; +template <> struct integral { using type = long; }; +template <> struct integral { using type = unsigned long; }; +template <> struct integral { using type = long long; }; +template <> struct integral { using type = unsigned long long; }; + +template +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; +using false_type = integral_constant; + +template struct conditional { using type = T; }; +template struct conditional { using type = F; }; + +template struct conjunction : true_type {}; +template struct conjunction : B1 {}; +template +struct conjunction : conditional, B1>::type {}; + + +} // namespace types diff --git a/src/include/enum_bitfields.h b/src/include/enum_bitfields.h new file mode 100644 index 0000000..49f9acc --- /dev/null +++ b/src/include/enum_bitfields.h @@ -0,0 +1,89 @@ +#pragma once + +#include "basic_types.h" + +namespace bitfields { + +template +constexpr bool is_enum_bitfield(E) { return false; } + +template +struct enum_or_int { + static constexpr bool value = + is_enum_bitfield(E{}) || types::is_integral::value; +}; + +template +struct both_enum_or_int { + static constexpr bool value = + types::conjunction< enum_or_int, enum_or_int >::value; +}; + +template +constexpr typename types::enable_if::value,E>::type& +operator |= (E &lhs, F rhs) +{ + return lhs = static_cast( + static_cast::type>(lhs) | + static_cast::type>(rhs)); +} + +template +constexpr typename types::enable_if::value,E>::type& +operator &= (E &lhs, F rhs) +{ + return lhs = static_cast( + static_cast::type>(lhs) & + static_cast::type>(rhs)); +} + +template +constexpr typename types::enable_if::value,E>::type& +operator ^= (E &lhs, F rhs) +{ + return lhs = static_cast( + static_cast::type>(lhs) ^ + static_cast::type>(rhs)); +} + +template +constexpr typename types::enable_if::value,E>::type +operator & (E lhs, F rhs) { return lhs &= rhs; } + +template +constexpr typename types::enable_if::value,E>::type +operator | (E lhs, F rhs) { return lhs |= rhs; } + +template +constexpr typename types::enable_if::value,E>::type +operator ^ (E lhs, F rhs) { return lhs ^= rhs; } + +template +constexpr typename types::enable_if::type +operator ~ (E rhs) { return static_cast(~static_cast::type>(rhs)); } + +template +constexpr typename types::enable_if::type +operator ! (E rhs) { return static_cast::type>(rhs) == 0; } + +/// Override logical-and to mean 'rhs contains all bits in lhs' +template +constexpr typename types::enable_if::type +operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; } + +/// Generic 'has' for non-marked bitfields +template +constexpr bool has(E set, F flags) +{ + return + (static_cast::type>(set) & + static_cast::type>(flags)) == + static_cast::type>(flags); +} + +} // namespace bitfields + +#define is_bitfield(name) \ + constexpr bool is_enum_bitfield(name) { return true; } \ + using namespace ::bitfields; + diff --git a/src/kernel/acpi_tables.h b/src/kernel/acpi_tables.h index b488ddd..22a66f4 100644 --- a/src/kernel/acpi_tables.h +++ b/src/kernel/acpi_tables.h @@ -3,8 +3,8 @@ #include #include +#include "enum_bitfields.h" #include "kutil/coord.h" -#include "kutil/enum_bitfields.h" #include "kutil/misc.h" struct acpi_table_header diff --git a/src/kernel/apic.h b/src/kernel/apic.h index 3c52113..8c05349 100644 --- a/src/kernel/apic.h +++ b/src/kernel/apic.h @@ -3,7 +3,7 @@ /// Classes to control both local and I/O APICs. #include -#include "kutil/enum_bitfields.h" +#include "enum_bitfields.h" enum class isr : uint8_t; diff --git a/src/kernel/gdt.h b/src/kernel/gdt.h index e78ce87..3651740 100644 --- a/src/kernel/gdt.h +++ b/src/kernel/gdt.h @@ -3,7 +3,7 @@ /// Definitions relating to a CPU's GDT table #include -#include "kutil/enum_bitfields.h" +#include "enum_bitfields.h" class TSS; diff --git a/src/kernel/memory_bootstrap.cpp b/src/kernel/memory_bootstrap.cpp index 286cbcb..2a00909 100644 --- a/src/kernel/memory_bootstrap.cpp +++ b/src/kernel/memory_bootstrap.cpp @@ -3,8 +3,8 @@ #include "kernel_args.h" #include "j6/init.h" +#include "enum_bitfields.h" #include "kutil/assert.h" -#include "kutil/enum_bitfields.h" #include "kutil/heap_allocator.h" #include "kutil/no_construct.h" diff --git a/src/kernel/objects/vm_area.h b/src/kernel/objects/vm_area.h index 8753aeb..7da6d8d 100644 --- a/src/kernel/objects/vm_area.h +++ b/src/kernel/objects/vm_area.h @@ -5,8 +5,8 @@ #include #include +#include "enum_bitfields.h" #include "j6/signals.h" -#include "kutil/enum_bitfields.h" #include "kutil/vector.h" #include "kernel_memory.h" diff --git a/src/kernel/page_table.h b/src/kernel/page_table.h index e780e8f..9dcecfc 100644 --- a/src/kernel/page_table.h +++ b/src/kernel/page_table.h @@ -3,7 +3,7 @@ /// Helper structures for dealing with page tables. #include -#include "kutil/enum_bitfields.h" +#include "enum_bitfields.h" #include "kernel_memory.h" struct free_page_header; diff --git a/src/kernel/vm_space.h b/src/kernel/vm_space.h index 8dcd3ca..8f66351 100644 --- a/src/kernel/vm_space.h +++ b/src/kernel/vm_space.h @@ -3,7 +3,7 @@ /// Structure for tracking a range of virtual memory addresses #include -#include "kutil/enum_bitfields.h" +#include "enum_bitfields.h" #include "kutil/spinlock.h" #include "kutil/vector.h" #include "page_table.h" diff --git a/src/libraries/elf/include/elf/headers.h b/src/libraries/elf/include/elf/headers.h index cd6bbf4..f1aa400 100644 --- a/src/libraries/elf/include/elf/headers.h +++ b/src/libraries/elf/include/elf/headers.h @@ -1,6 +1,6 @@ #pragma once #include -#include "kutil/enum_bitfields.h" +#include "enum_bitfields.h" namespace elf { @@ -95,4 +95,4 @@ struct section_header } // namespace elf -IS_BITFIELD(elf::section_flags); +is_bitfield(elf::section_flags); diff --git a/src/libraries/kutil/include/kutil/enum_bitfields.h b/src/libraries/kutil/include/kutil/enum_bitfields.h deleted file mode 100644 index 6e24c2b..0000000 --- a/src/libraries/kutil/include/kutil/enum_bitfields.h +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include - -namespace kutil { -namespace bitfields { - -template -constexpr bool is_enum_bitfield(E) { return false; } - -template -struct enum_or_int { - static constexpr bool value = - is_enum_bitfield(E{}) || std::is_integral::value; -}; - -template -struct both_enum_or_int { - static constexpr bool value = - std::conjunction< enum_or_int, enum_or_int >::value; -}; - -template -struct integral { using type = typename std::underlying_type::type; }; - -template <> struct integral { using type = char; }; -template <> struct integral { using type = unsigned char; }; -template <> struct integral { using type = short; }; -template <> struct integral { using type = unsigned short; }; -template <> struct integral { using type = int; }; -template <> struct integral { using type = unsigned int; }; -template <> struct integral { using type = long; }; -template <> struct integral { using type = unsigned long; }; -template <> struct integral { using type = long long; }; -template <> struct integral { using type = unsigned long long; }; - -template -constexpr typename std::enable_if::value,E>::type& -operator |= (E &lhs, F rhs) -{ - return lhs = static_cast( - static_cast::type>(lhs) | - static_cast::type>(rhs)); -} - -template -constexpr typename std::enable_if::value,E>::type& -operator &= (E &lhs, F rhs) -{ - return lhs = static_cast( - static_cast::type>(lhs) & - static_cast::type>(rhs)); -} - -template -constexpr typename std::enable_if::value,E>::type& -operator ^= (E &lhs, F rhs) -{ - return lhs = static_cast( - static_cast::type>(lhs) ^ - static_cast::type>(rhs)); -} - -template -constexpr typename std::enable_if::value,E>::type -operator & (E lhs, F rhs) { return lhs &= rhs; } - -template -constexpr typename std::enable_if::value,E>::type -operator | (E lhs, F rhs) { return lhs |= rhs; } - -template -constexpr typename std::enable_if::value,E>::type -operator ^ (E lhs, F rhs) { return lhs ^= rhs; } - -template -constexpr typename std::enable_if::type -operator ~ (E rhs) { return static_cast(~static_cast::type>(rhs)); } - -template -constexpr typename std::enable_if::type -operator ! (E rhs) { return static_cast::type>(rhs) == 0; } - -/// Override logical-and to mean 'rhs contains all bits in lhs' -template -constexpr typename std::enable_if::type -operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; } - -/// Generic 'has' for non-marked bitfields -template -constexpr bool has(E set, F flags) -{ - return - (static_cast::type>(set) & - static_cast::type>(flags)) == - static_cast::type>(flags); -} - -} // namespace bitfields -} // namespace kutil - -#define is_bitfield(name) \ - constexpr bool is_enum_bitfield(name) { return true; } \ - using namespace kutil::bitfields; -