From 80ff0d568295af1beac900a530d7001341eddad7 Mon Sep 17 00:00:00 2001 From: Wankupi <2893353848@qq.com> Date: Tue, 23 Jul 2024 18:46:21 +0800 Subject: [PATCH] style: use tab replace spaces every one could change the length of tab but not of space --- include/bit.h | 52 +++++++------- include/bit_impl.h | 101 ++++++++++++++------------- include/concept.h | 44 ++++++------ include/cpu.h | 2 +- include/debug.h | 72 ++++++++++--------- include/module.h | 2 +- include/operator.h | 159 +++++++++++++++++++++--------------------- include/reflect.h | 149 ++++++++++++++++++++++----------------- include/register.h | 56 +++++++-------- include/synchronize.h | 70 ++++++++++--------- include/tools.h | 16 ++--- include/wire.h | 153 ++++++++++++++++++++-------------------- 12 files changed, 455 insertions(+), 421 deletions(-) diff --git a/include/bit.h b/include/bit.h index d50ec7d..5b2f37e 100644 --- a/include/bit.h +++ b/include/bit.h @@ -1,50 +1,50 @@ #pragma once #include "concept.h" #include "debug.h" -#include #include #include +#include namespace dark { -template +template struct Bit { - private: - static_assert(0 < _Nm && _Nm <= kMaxLength, - "Bit: _Nm out of range. Should be in [1, kMaxLength]"); - - max_size_t _M_data : _Nm; // Real storage +private: + static_assert(0 < _Nm && _Nm <= kMaxLength, + "Bit: _Nm out of range. Should be in [1, kMaxLength]"); - template - static constexpr void _M_range_check(); + max_size_t _M_data : _Nm; // Real storage - public: - static constexpr std::size_t _Bit_Len = _Nm; + template + static constexpr void _M_range_check(); - constexpr Bit(max_size_t data = 0) : _M_data(data) {} +public: + static constexpr std::size_t _Bit_Len = _Nm; - constexpr explicit operator max_size_t() const { return this->_M_data; } + constexpr Bit(max_size_t data = 0) : _M_data(data) {} - template - requires ((_Tp::_Bit_Len + ...) == _Nm) - constexpr Bit(const _Tp &...args); + constexpr explicit operator max_size_t() const { return this->_M_data; } - template _Tp> - constexpr Bit &operator=(const _Tp &val); + template + requires((_Tp::_Bit_Len + ...) == _Nm) + constexpr Bit(const _Tp &...args); - template _Tp> - constexpr void set(const _Tp &val); + template _Tp> + constexpr Bit &operator=(const _Tp &val); - template - constexpr auto range() const -> Bit <_Hi - _Lo + 1>; + template _Tp> + constexpr void set(const _Tp &val); - template - constexpr auto slice(std::size_t pos) const -> Bit <_Len>; + template + constexpr auto range() const -> Bit<_Hi - _Lo + 1>; - constexpr Bit <1> operator [](std::size_t pos) const { return this->slice(pos); } + template + constexpr auto slice(std::size_t pos) const -> Bit<_Len>; + + constexpr Bit<1> operator[](std::size_t pos) const { return this->slice(pos); } }; -template +template Bit(_Tp...) -> Bit<(_Tp::_Bit_Len + ...)>; } // namespace dark diff --git a/include/bit_impl.h b/include/bit_impl.h index e67ec17..609bdec 100644 --- a/include/bit_impl.h +++ b/include/bit_impl.h @@ -3,84 +3,87 @@ namespace dark { -template +template constexpr auto int_concat(max_size_t arg) { return arg; } -template -constexpr auto int_concat(max_size_t arg, auto ...args) { - return (arg << (_Lens + ...)) | int_concat<_Lens...>(args...); +template +constexpr auto int_concat(max_size_t arg, auto... args) { + return (arg << (_Lens + ...)) | int_concat<_Lens...>(args...); } -template +template constexpr auto sign_extend(max_size_t val) { - static_assert(_Old < _New, "sign_extend: _Old should be less than _New"); - struct { max_ssize_t _M_data : _Old; } tmp; - return Bit<_New>(tmp._M_data = val); + static_assert(_Old < _New, "sign_extend: _Old should be less than _New"); + struct { + max_ssize_t _M_data : _Old; + } tmp; + return Bit<_New>(tmp._M_data = val); } -template -constexpr auto sign_extend(const _Tp & val) { - return sign_extend<_Tp::_Bit_Len, _New>(static_cast(val)); +template +constexpr auto sign_extend(const _Tp &val) { + return sign_extend<_Tp::_Bit_Len, _New>(static_cast(val)); } -template +template constexpr auto zero_extend(max_size_t val) { - static_assert(_Old < _New, "zero_extend: _Old should be less than _New"); - struct { max_size_t _M_data : _Old; } tmp; - return Bit<_New>(tmp._M_data = val); + static_assert(_Old < _New, "zero_extend: _Old should be less than _New"); + struct { + max_size_t _M_data : _Old; + } tmp; + return Bit<_New>(tmp._M_data = val); } -template +template constexpr auto zero_extend(const _Tp &val) { - return zero_extend<_Tp::_Bit_Len, _New>(static_cast(val)); + return zero_extend<_Tp::_Bit_Len, _New>(static_cast(val)); } -template -template -requires ((_Tp::_Bit_Len + ...) == _Nm) +template +template + requires((_Tp::_Bit_Len + ...) == _Nm) constexpr Bit<_Nm>::Bit(const _Tp &...args) - : _M_data(int_concat<_Tp::_Bit_Len...>(static_cast(args)...)) {} + : _M_data(int_concat<_Tp::_Bit_Len...>(static_cast(args)...)) {} -template -template _Tp> +template +template _Tp> constexpr Bit<_Nm> &Bit<_Nm>::operator=(const _Tp &val) { - this->_M_data = static_cast(val); - return *this; + this->_M_data = static_cast(val); + return *this; } -template -template +template +template constexpr void Bit<_Nm>::_M_range_check() { - static_assert(_Lo <= _Hi, "Bit::range_check: _Lo should be no greater than _Hi"); - static_assert(_Hi < _Nm, "Bit::range_check: _Hi should be less than _Nm"); + static_assert(_Lo <= _Hi, "Bit::range_check: _Lo should be no greater than _Hi"); + static_assert(_Hi < _Nm, "Bit::range_check: _Hi should be less than _Nm"); } -template -template _Tp> +template +template _Tp> constexpr void Bit<_Nm>::set(const _Tp &val) { - this->_M_range_check<_Hi, _Lo>(); - auto data = static_cast(val); - constexpr auto _Length = _Hi - _Lo + 1; - auto mask = make_mask<_Length> << _Lo; - this->_M_data = (this->_M_data & ~mask) | ((data << _Lo) & mask); + this->_M_range_check<_Hi, _Lo>(); + auto data = static_cast(val); + constexpr auto _Length = _Hi - _Lo + 1; + auto mask = make_mask<_Length> << _Lo; + this->_M_data = (this->_M_data & ~mask) | ((data << _Lo) & mask); } -template -template -constexpr auto Bit<_Nm>::range() const -> Bit <_Hi - _Lo + 1> { - this->_M_range_check<_Hi, _Lo>(); - constexpr auto _Length = _Hi - _Lo + 1; - return Bit<_Length>(this->_M_data >> _Lo); +template +template +constexpr auto Bit<_Nm>::range() const -> Bit<_Hi - _Lo + 1> { + this->_M_range_check<_Hi, _Lo>(); + constexpr auto _Length = _Hi - _Lo + 1; + return Bit<_Length>(this->_M_data >> _Lo); } -template -template -constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit <_Len> { - static_assert(_Len <= _Nm, "Bit::slice: _Len should be no greater than _Nm"); - debug::assert(pos <= _Nm - _Len, "Bit::slice: pos should be less than _Nm - _Len"); - return Bit<_Len>(this->_M_data >> pos); +template +template +constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit<_Len> { + static_assert(_Len <= _Nm, "Bit::slice: _Len should be no greater than _Nm"); + debug::assert(pos <= _Nm - _Len, "Bit::slice: pos should be less than _Nm - _Len"); + return Bit<_Len>(this->_M_data >> pos); } - } // namespace dark diff --git a/include/concept.h b/include/concept.h index 2145e9f..6e1ef93 100644 --- a/include/concept.h +++ b/include/concept.h @@ -1,7 +1,7 @@ #pragma once -#include -#include #include +#include +#include namespace dark { @@ -10,45 +10,43 @@ using max_ssize_t = std::int32_t; static constexpr std::size_t kMaxLength = std::numeric_limits::digits; -template +template consteval max_size_t make_mask() { - static_assert(_Len <= kMaxLength, "Mask length out of range"); - return _Len == kMaxLength ? ~max_size_t(0) : (max_size_t(1) << _Len) - 1; + static_assert(_Len <= kMaxLength, "Mask length out of range"); + return _Len == kMaxLength ? ~max_size_t(0) : (max_size_t(1) << _Len) - 1; } } // namespace dark namespace dark::concepts { -template -using func_t = void(*)(_Tp); +template +using func_t = void (*)(_Tp); -template -concept implicit_convertible_to = requires(_From &a, func_t <_To> b) { - b(a); // Can implicitly convert +template +concept implicit_convertible_to = requires(_From &a, func_t<_To> b) { + b(a); // Can implicitly convert }; -template +template concept explicit_convertible_to = - !implicit_convertible_to <_From, _To> -&& std::constructible_from <_To, _From>; + !implicit_convertible_to<_From, _To> && std::constructible_from<_To, _From>; -template +template concept has_length = requires { { +_Tp::_Bit_Len } -> std::same_as ; }; -template -concept bit_type = has_length <_Tp> && explicit_convertible_to <_Tp, max_size_t>; +template +concept bit_type = has_length<_Tp> && explicit_convertible_to<_Tp, max_size_t>; -template -concept int_type = !has_length <_Tp> && implicit_convertible_to <_Tp, max_size_t>; +template +concept int_type = !has_length<_Tp> && implicit_convertible_to<_Tp, max_size_t>; -template +template concept bit_match = - (bit_type <_Lhs> && bit_type <_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len) -|| (int_type <_Lhs> || int_type <_Rhs>); + (bit_type<_Lhs> && bit_type<_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len) || (int_type<_Lhs> || int_type<_Rhs>); -template +template concept bit_convertible = - (bit_type <_Tp> && _Tp::_Bit_Len == _Len) || int_type <_Tp>; + (bit_type<_Tp> && _Tp::_Bit_Len == _Len) || int_type<_Tp>; } // namespace dark::concepts diff --git a/include/cpu.h b/include/cpu.h index 215003f..7d63df6 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -48,4 +48,4 @@ public: } }; -}// namespace dark +} // namespace dark diff --git a/include/debug.h b/include/debug.h index 01f4e53..dad80be 100644 --- a/include/debug.h +++ b/include/debug.h @@ -8,60 +8,64 @@ namespace dark::debug { /** - * Copied from https://en.cppreference.com/w/cpp/utility/unreachable + * Copied from https://en.cppreference.com/w/cpp/utility/unreachable * If compiled under C++23, just use std::unreachable() instead. */ [[noreturn]] inline void unreachable() { #if __cplusplus > 202002L - std::unreachable(); + std::unreachable(); #elif defined(_MSC_VER) && !defined(__clang__) // MSVC - // Uses compiler specific extensions if possible. - // Even if no extension is used, undefined behavior is still raised by - // an empty function body and the noreturn attribute. - __assume(false); -#else // GCC, Clang - __builtin_unreachable(); + // Uses compiler specific extensions if possible. + // Even if no extension is used, undefined behavior is still raised by + // an empty function body and the noreturn attribute. + __assume(false); +#else // GCC, Clang + __builtin_unreachable(); #endif } -template +template struct assert { #ifdef _DEBUG - explicit assert(_Tp &&condition, _Args &&...args, - std::source_location location = std::source_location::current()) { - if (condition) return; - std::cerr << "Assertion failed at: " - << location.file_name() << ":" << location.line() << "\n"; - if constexpr (sizeof...(args) != 0) { - std::cerr << "Message: "; - ((std::cerr << args), ...) << std::endl; - } - std::exit(EXIT_FAILURE); - } + explicit assert(_Tp &&condition, _Args &&...args, + std::source_location location = std::source_location::current()) { + if (condition) return; + std::cerr << "Assertion failed at: " + << location.file_name() << ":" << location.line() << "\n"; + if constexpr (sizeof...(args) != 0) { + std::cerr << "Message: "; + ((std::cerr << args), ...) << std::endl; + } + std::exit(EXIT_FAILURE); + } #else - explicit assert(_Tp &&, _Args &&...) {} + explicit assert(_Tp &&, _Args &&...) {} #endif }; -template +template assert(_Tp &&, _Args &&...) -> assert<_Tp, _Args...>; -template +template struct DebugValue { #ifdef _DEBUG - private: - _Tp _M_value = _Default; - public: - auto get_value() const { return this->_M_value; } - auto set_value(_Tp value) { this->_M_value = value; } +private: + _Tp _M_value = _Default; + +public: + auto get_value() const { return this->_M_value; } + auto set_value(_Tp value) { this->_M_value = value; } #else - public: - auto get_value() const { return _Default; } - auto set_value(_Tp) { /* do nothing */ } +public: + auto get_value() const { return _Default; } + auto set_value(_Tp) { /* do nothing */ } #endif - public: - explicit operator _Tp() const { return this->get_value(); } - DebugValue &operator=(_Tp value) { this->set_value(value); return *this; } +public: + explicit operator _Tp() const { return this->get_value(); } + DebugValue &operator=(_Tp value) { + this->set_value(value); + return *this; + } }; } // namespace dark::debug diff --git a/include/module.h b/include/module.h index 674fafb..a9a7a46 100644 --- a/include/module.h +++ b/include/module.h @@ -16,4 +16,4 @@ struct Module : public ModuleBase, public _Tinput, public _Toutput, protected _T } }; -}// namespace dark +} // namespace dark diff --git a/include/operator.h b/include/operator.h index 654d50b..23bb701 100644 --- a/include/operator.h +++ b/include/operator.h @@ -3,127 +3,128 @@ namespace dark { +using dark::concepts::bit_match; using dark::concepts::bit_type; using dark::concepts::int_type; -using dark::concepts::bit_match; -template -constexpr auto cast(const _Tp& value) { - return static_cast (value); +template +constexpr auto cast(const _Tp &value) { + return static_cast(value); } -template +template consteval auto get_common_length() -> std::size_t { - static_assert(bit_match <_Tp, _Up>); - if constexpr (bit_type <_Tp>) { - return _Tp::_Bit_Len; - } else { - static_assert(bit_type <_Up>, "Invalid common length"); - return _Up::_Bit_Len; - } + static_assert(bit_match<_Tp, _Up>); + if constexpr (bit_type<_Tp>) { + return _Tp::_Bit_Len; + } + else { + static_assert(bit_type<_Up>, "Invalid common length"); + return _Up::_Bit_Len; + } } -template -requires bit_match <_Tp, _Up> -constexpr auto operator + (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) + cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator+(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) + cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator - (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) - cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator-(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) - cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator * (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) * cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator*(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) * cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator / (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) / cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator/(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) / cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator & (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) & cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator&(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) & cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator | (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) | cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator|(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) | cast(rhs)); } -template -requires bit_match <_Tp, _Up> -constexpr auto operator ^ (const _Tp &lhs, const _Up &rhs) { - constexpr auto _Len = get_common_length <_Tp, _Up>(); - return Bit <_Len> (cast(lhs) ^ cast(rhs)); +template + requires bit_match<_Tp, _Up> +constexpr auto operator^(const _Tp &lhs, const _Up &rhs) { + constexpr auto _Len = get_common_length<_Tp, _Up>(); + return Bit<_Len>(cast(lhs) ^ cast(rhs)); } -template -concept int_or_bit = int_type <_Tp> || bit_type <_Tp>; +template +concept int_or_bit = int_type<_Tp> || bit_type<_Tp>; -template -constexpr auto operator << (const _Tp &lhs, const _Up &rhs) { - return Bit <_Tp::_Bit_Len> (cast(lhs) << (cast(rhs) & kMaxLength)); +template +constexpr auto operator<<(const _Tp &lhs, const _Up &rhs) { + return Bit<_Tp::_Bit_Len>(cast(lhs) << (cast(rhs) & kMaxLength)); } -template -constexpr auto operator >> (const _Tp &lhs, const _Up &rhs) { - return Bit <_Tp::_Bit_Len> (cast(lhs) >> (cast(rhs) & kMaxLength)); +template +constexpr auto operator>>(const _Tp &lhs, const _Up &rhs) { + return Bit<_Tp::_Bit_Len>(cast(lhs) >> (cast(rhs) & kMaxLength)); } -template -constexpr auto operator ~ (const _Tp &value) { - return Bit <_Tp::_Bit_Len> (~cast(value)); +template +constexpr auto operator~(const _Tp &value) { + return Bit<_Tp::_Bit_Len>(~cast(value)); } -template -constexpr auto operator ! (const _Tp &value) { - return ~value; +template +constexpr auto operator!(const _Tp &value) { + return ~value; } -template -constexpr auto operator + (const _Tp &value) { - return Bit <_Tp::_Bit_Len> (+cast(value)); +template +constexpr auto operator+(const _Tp &value) { + return Bit<_Tp::_Bit_Len>(+cast(value)); } -template -constexpr auto operator - (const _Tp &value) { - return Bit <_Tp::_Bit_Len> (-cast(value)); +template +constexpr auto operator-(const _Tp &value) { + return Bit<_Tp::_Bit_Len>(-cast(value)); } -template -constexpr bool operator && (const _Tp &lhs, const _Up &rhs) { - return cast(lhs) && cast(rhs); +template +constexpr bool operator&&(const _Tp &lhs, const _Up &rhs) { + return cast(lhs) && cast(rhs); } -template -constexpr bool operator || (const _Tp &lhs, const _Up &rhs) { - return cast(lhs) || cast(rhs); +template +constexpr bool operator||(const _Tp &lhs, const _Up &rhs) { + return cast(lhs) || cast(rhs); } -template -constexpr bool operator == (const _Tp &lhs, const _Up &rhs) { - return cast(lhs) == cast(rhs); +template +constexpr bool operator==(const _Tp &lhs, const _Up &rhs) { + return cast(lhs) == cast(rhs); } -template -constexpr auto operator <=> (const _Tp &lhs, const _Up &rhs) { - return cast(lhs) <=> cast(rhs); +template +constexpr auto operator<=>(const _Tp &lhs, const _Up &rhs) { + return cast(lhs) <=> cast(rhs); } diff --git a/include/reflect.h b/include/reflect.h index d3a1dfd..90bd065 100644 --- a/include/reflect.h +++ b/include/reflect.h @@ -1,81 +1,104 @@ #pragma once -#include #include +#include namespace dark::reflect { /* A init helper to get the size of a struct. */ -struct init_helper { template operator _Tp(); }; +struct init_helper { + template + operator _Tp(); +}; /* A size helper to get the size of a struct. */ -template requires std::is_aggregate_v <_Tp> +template + requires std::is_aggregate_v<_Tp> inline consteval auto member_size_aux(auto &&...args) -> std::size_t { - constexpr std::size_t size = sizeof...(args); - constexpr std::size_t maximum = 114; - if constexpr (size > maximum) { - static_assert (sizeof(_Tp) == 0, "The struct has too many members."); - } else if constexpr (!requires {_Tp { args... }; }) { - return size - 1; - } else { - return member_size_aux <_Tp> (args..., init_helper {}); - } + constexpr std::size_t size = sizeof...(args); + constexpr std::size_t maximum = 114; + if constexpr (size > maximum) { + static_assert(sizeof(_Tp) == 0, "The struct has too many members."); + } + else if constexpr (!requires { _Tp{args...}; }) { + return size - 1; + } + else { + return member_size_aux<_Tp>(args..., init_helper{}); + } } /* Return the member size for a aggregate type without base. */ -template requires std::is_aggregate_v <_Tp> -inline consteval auto member_size(_Tp &) -> std::size_t { return member_size_aux <_Tp> (); } +template + requires std::is_aggregate_v<_Tp> +inline consteval auto member_size(_Tp &) -> std::size_t { return member_size_aux<_Tp>(); } -template requires std::is_aggregate_v <_Tp> -inline consteval auto member_size() -> std::size_t { return member_size_aux <_Tp> (); } +template + requires std::is_aggregate_v<_Tp> +inline consteval auto member_size() -> std::size_t { return member_size_aux<_Tp>(); } -template requires std::is_aggregate_v <_Tp> +template + requires std::is_aggregate_v<_Tp> auto tuplify(_Tp &value) { - constexpr auto size = member_size <_Tp> (); - if constexpr (size == 1) { - auto &[x0] = value; - return std::forward_as_tuple(x0); - } else if constexpr (size == 2) { - auto &[x0, x1] = value; - return std::forward_as_tuple(x0, x1); - } else if constexpr (size == 3) { - auto &[x0, x1, x2] = value; - return std::forward_as_tuple(x0, x1, x2); - } else if constexpr (size == 4) { - auto &[x0, x1, x2, x3] = value; - return std::forward_as_tuple(x0, x1, x2, x3); - } else if constexpr (size == 5) { - auto &[x0, x1, x2, x3, x4] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4); - } else if constexpr (size == 6) { - auto &[x0, x1, x2, x3, x4, x5] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5); - } else if constexpr (size == 7) { - auto &[x0, x1, x2, x3, x4, x5, x6] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6); - } else if constexpr (size == 8) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7); - } else if constexpr (size == 9) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8); - } else if constexpr (size == 10) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); - } else if constexpr (size == 11) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10); - } else if constexpr (size == 12) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11); - } else if constexpr (size == 13) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12); - } else if constexpr (size == 14) { - auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13] = value; - return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13); - } else { - static_assert (sizeof(_Tp) == 0, "The struct has too many members."); - } + constexpr auto size = member_size<_Tp>(); + if constexpr (size == 1) { + auto &[x0] = value; + return std::forward_as_tuple(x0); + } + else if constexpr (size == 2) { + auto &[x0, x1] = value; + return std::forward_as_tuple(x0, x1); + } + else if constexpr (size == 3) { + auto &[x0, x1, x2] = value; + return std::forward_as_tuple(x0, x1, x2); + } + else if constexpr (size == 4) { + auto &[x0, x1, x2, x3] = value; + return std::forward_as_tuple(x0, x1, x2, x3); + } + else if constexpr (size == 5) { + auto &[x0, x1, x2, x3, x4] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4); + } + else if constexpr (size == 6) { + auto &[x0, x1, x2, x3, x4, x5] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5); + } + else if constexpr (size == 7) { + auto &[x0, x1, x2, x3, x4, x5, x6] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6); + } + else if constexpr (size == 8) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7); + } + else if constexpr (size == 9) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8); + } + else if constexpr (size == 10) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9); + } + else if constexpr (size == 11) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10); + } + else if constexpr (size == 12) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11); + } + else if constexpr (size == 13) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12); + } + else if constexpr (size == 14) { + auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13] = value; + return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13); + } + else { + static_assert(sizeof(_Tp) == 0, "The struct has too many members."); + } } } // namespace dark::reflect diff --git a/include/register.h b/include/register.h index 0b79264..136bf31 100644 --- a/include/register.h +++ b/include/register.h @@ -1,46 +1,46 @@ #pragma once -#include "debug.h" #include "concept.h" +#include "debug.h" namespace dark { -template +template struct Register { - private: - static_assert(0 < _Len && _Len <= kMaxLength, - "Register: _Len must be in range [1, kMaxLength]."); +private: + static_assert(0 < _Len && _Len <= kMaxLength, + "Register: _Len must be in range [1, kMaxLength]."); - friend class Visitor; + friend class Visitor; - max_size_t _M_old : _Len; - max_size_t _M_new : _Len; + max_size_t _M_old : _Len; + max_size_t _M_new : _Len; - [[no_unique_address]] - debug::DebugValue _M_assigned; + [[no_unique_address]] + debug::DebugValue _M_assigned; - void sync() { - this->_M_assigned = false; - this->_M_old = this->_M_new; - } + void sync() { + this->_M_assigned = false; + this->_M_old = this->_M_new; + } - public: - static constexpr std::size_t _Bit_Len = _Len; +public: + static constexpr std::size_t _Bit_Len = _Len; - Register() : _M_old(), _M_new(), _M_assigned() {} + Register() : _M_old(), _M_new(), _M_assigned() {} - Register(Register &&) = delete; - Register(const Register &) = delete; - Register &operator=(Register &&) = delete; - Register &operator=(const Register &rhs) = delete; + Register(Register &&) = delete; + Register(const Register &) = delete; + Register &operator=(Register &&) = delete; + Register &operator=(const Register &rhs) = delete; - template _Tp> - void operator <= (const _Tp &value) { - debug::assert(!this->_M_assigned, "Register is double assigned in this cycle."); - this->_M_assigned = true; - this->_M_new = static_cast (value); - } + template _Tp> + void operator<=(const _Tp &value) { + debug::assert(!this->_M_assigned, "Register is double assigned in this cycle."); + this->_M_assigned = true; + this->_M_new = static_cast(value); + } - explicit operator max_size_t() const { return this->_M_old; } + explicit operator max_size_t() const { return this->_M_old; } }; } // namespace dark diff --git a/include/synchronize.h b/include/synchronize.h index b3decd5..af67710 100644 --- a/include/synchronize.h +++ b/include/synchronize.h @@ -5,56 +5,62 @@ namespace dark { struct Visitor { - template - static constexpr bool is_syncable_v = - requires(_Tp &val) { { val.sync() } -> std::same_as; }; + template + static constexpr bool is_syncable_v = + requires(_Tp &val) { { val.sync() } -> std::same_as; }; - template requires is_syncable_v<_Tp> - static void sync(_Tp &val) { val.sync(); } + template + requires is_syncable_v<_Tp> + static void sync(_Tp &val) { val.sync(); } - template - static _Base &cast(_Tp &value) { return static_cast<_Base &>(value); } + template + static _Base &cast(_Tp &value) { return static_cast<_Base &>(value); } }; -template +template struct SyncTags {}; -template +template static constexpr bool is_valid_tag_v = false; -template +template static constexpr bool is_valid_tag_v> = true; -template +template concept has_valid_tag = is_valid_tag_v; -template +template static constexpr bool is_std_array_v = std::is_array_v<_Tp>; -template +template static constexpr bool is_std_array_v> = true; -template +template inline void sync_member(_Tp &value); -template +template inline void sync_by_tag(_Tp &value, SyncTags<_Base...>) { - (sync_member(Visitor::cast<_Tp, _Base>(value)), ...); + (sync_member(Visitor::cast<_Tp, _Base>(value)), ...); } -template +template inline void sync_member(_Tp &value) { - if constexpr (std::is_const_v <_Tp>) { - /* Do nothing! Constant members need no synchronization! */ - } else if constexpr (is_std_array_v<_Tp>) { - for (auto &member : value) sync_member(member); - } else if constexpr (Visitor::is_syncable_v<_Tp>) { - Visitor::sync(value); - } else if constexpr (has_valid_tag<_Tp>) { - sync_by_tag(value, typename _Tp::Tags {}); - } else if constexpr (std::is_aggregate_v<_Tp>) { - auto &&tuple = reflect::tuplify(value); - std::apply([](auto &...members) { (sync_member(members), ...); }, tuple); - } else { - static_assert(sizeof(_Tp) == 0, "This type is not syncable."); - } + if constexpr (std::is_const_v<_Tp>) { + /* Do nothing! Constant members need no synchronization! */ + } + else if constexpr (is_std_array_v<_Tp>) { + for (auto &member: value) sync_member(member); + } + else if constexpr (Visitor::is_syncable_v<_Tp>) { + Visitor::sync(value); + } + else if constexpr (has_valid_tag<_Tp>) { + sync_by_tag(value, typename _Tp::Tags{}); + } + else if constexpr (std::is_aggregate_v<_Tp>) { + auto &&tuple = reflect::tuplify(value); + std::apply([](auto &...members) { (sync_member(members), ...); }, tuple); + } + else { + static_assert(sizeof(_Tp) == 0, "This type is not syncable."); + } } -} // namespace dark::hardware +} // namespace dark diff --git a/include/tools.h b/include/tools.h index 8a01306..a757337 100644 --- a/include/tools.h +++ b/include/tools.h @@ -1,31 +1,31 @@ #pragma once #include "bit.h" #include "bit_impl.h" -#include "wire.h" +#include "operator.h" #include "register.h" #include "synchronize.h" -#include "operator.h" +#include "wire.h" using dark::Bit; using dark::sign_extend; using dark::zero_extend; -using dark::Wire; using dark::Register; +using dark::Wire; -using dark::SyncTags; using dark::sync_member; +using dark::SyncTags; using dark::Visitor; using dark::max_size_t; using dark::max_ssize_t; -template +template constexpr auto to_unsigned(const _Tp &x) { - return static_cast(x); + return static_cast(x); } -template +template constexpr auto to_signed(const _Tp &x) { - return static_cast(to_unsigned(x)); + return static_cast(to_unsigned(x)); } diff --git a/include/wire.h b/include/wire.h index 7074e34..92dc7cc 100644 --- a/include/wire.h +++ b/include/wire.h @@ -1,113 +1,112 @@ #pragma once -#include "debug.h" #include "concept.h" +#include "debug.h" #include namespace dark { namespace details { -template -concept WireFunction = - concepts::bit_convertible >, _Len>; + template + concept WireFunction = + concepts::bit_convertible>, _Len>; -struct FuncBase { - using _Ret_t = max_size_t; - using _Cpy_t = FuncBase *; - virtual _Ret_t call() const = 0; - virtual _Cpy_t copy() const = 0; - virtual ~FuncBase() = default; -}; + struct FuncBase { + using _Ret_t = max_size_t; + using _Cpy_t = FuncBase *; + virtual _Ret_t call() const = 0; + virtual _Cpy_t copy() const = 0; + virtual ~FuncBase() = default; + }; -template _Fn> -struct FuncImpl final : FuncBase { - _Fn _M_lambda; + template _Fn> + struct FuncImpl final : FuncBase { + _Fn _M_lambda; - template - FuncImpl(_Tp &&fn) : _M_lambda(std::forward <_Tp> (fn)) {} + template + FuncImpl(_Tp &&fn) : _M_lambda(std::forward<_Tp>(fn)) {} - _Ret_t call() const override { return static_cast <_Ret_t> (this->_M_lambda()); } - _Cpy_t copy() const override { return new FuncImpl(*this); } -}; + _Ret_t call() const override { return static_cast<_Ret_t>(this->_M_lambda()); } + _Cpy_t copy() const override { return new FuncImpl(*this); } + }; -struct EmptyWire final : FuncBase { - _Ret_t call() const override { - debug::assert(false, "Empty wire is called."); - debug::unreachable(); - } - _Cpy_t copy() const override { return new EmptyWire; } -}; + struct EmptyWire final : FuncBase { + _Ret_t call() const override { + debug::assert(false, "Empty wire is called."); + debug::unreachable(); + } + _Cpy_t copy() const override { return new EmptyWire; } + }; } // namespace details -template +template struct Wire { - private: - static_assert(0 < _Len && _Len <= kMaxLength, - "Wire: _Len must be in range [1, kMaxLength]."); +private: + static_assert(0 < _Len && _Len <= kMaxLength, + "Wire: _Len must be in range [1, kMaxLength]."); - friend class Visitor; + friend class Visitor; - using _Manage_t = std::unique_ptr ; + using _Manage_t = std::unique_ptr; - _Manage_t _M_func; + _Manage_t _M_func; - mutable max_size_t _M_cache : _Len; - mutable bool _M_holds; + mutable max_size_t _M_cache : _Len; + mutable bool _M_holds; - [[no_unique_address]] - debug::DebugValue _M_assigned; + [[no_unique_address]] + debug::DebugValue _M_assigned; - void sync() { this->_M_holds = false; } +private: + void sync() { this->_M_holds = false; } - template _Fn> - static auto _M_new_func(_Fn &&fn) { - using _Decay_t = std::decay_t <_Fn>; - return new details::FuncImpl <_Len, _Decay_t> {std::forward <_Fn>(fn)}; - } + template _Fn> + static auto _M_new_func(_Fn &&fn) { + using _Decay_t = std::decay_t<_Fn>; + return new details::FuncImpl<_Len, _Decay_t>{std::forward<_Fn>(fn)}; + } - void _M_checked_assign() { - debug::assert(!this->_M_assigned, "Wire is assigned twice."); - this->_M_assigned = true; - } + void _M_checked_assign() { + debug::assert(!this->_M_assigned, "Wire is assigned twice."); + this->_M_assigned = true; + } - public: - static constexpr std::size_t _Bit_Len = _Len; +public: + static constexpr std::size_t _Bit_Len = _Len; - Wire() : - _M_func(new details::EmptyWire), - _M_cache(), _M_holds(), _M_assigned() {} + Wire() : _M_func(new details::EmptyWire), + _M_cache(), _M_holds(), _M_assigned() {} - explicit operator max_size_t() const { - if (this->_M_holds == false) { - this->_M_holds = true; - this->_M_cache = this->_M_func->call(); - } - return this->_M_cache; - } + explicit operator max_size_t() const { + if (this->_M_holds == false) { + this->_M_holds = true; + this->_M_cache = this->_M_func->call(); + } + return this->_M_cache; + } - Wire(Wire &&) = delete; - Wire(const Wire &) = delete; - Wire &operator=(Wire &&) = delete; - Wire &operator=(const Wire &rhs) = delete; + Wire(Wire &&) = delete; + Wire(const Wire &) = delete; + Wire &operator=(Wire &&) = delete; + Wire &operator=(const Wire &rhs) = delete; - template _Fn> - Wire(_Fn &&fn) : - _M_func(_M_new_func(std::forward <_Fn> (fn))), - _M_cache(), _M_holds(), _M_assigned() {} + template _Fn> + Wire(_Fn &&fn) : _M_func(_M_new_func(std::forward<_Fn>(fn))), + _M_cache(), _M_holds(), _M_assigned() {} - template _Fn> - Wire &operator=(_Fn &&fn) { - return this->assign(std::forward <_Fn> (fn)), *this; - } + template _Fn> + Wire &operator=(_Fn &&fn) { + return this->assign(std::forward<_Fn>(fn)), *this; + } - template _Fn> - void assign(_Fn &&fn) { - this->_M_checked_assign(); - this->_M_func.reset(_M_new_func(std::forward <_Fn> (fn))); - this->sync(); - } + template _Fn> + void assign(_Fn &&fn) { + this->_M_checked_assign(); + this->_M_func.reset(_M_new_func(std::forward<_Fn>(fn))); + this->sync(); + } };