style: use tab replace spaces
every one could change the length of tab but not of space
This commit is contained in:
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "concept.h"
|
#include "concept.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include <version>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <version>
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
|
@ -14,7 +14,9 @@ constexpr auto int_concat(max_size_t arg, auto ...args) {
|
|||||||
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
||||||
constexpr auto sign_extend(max_size_t val) {
|
constexpr auto sign_extend(max_size_t val) {
|
||||||
static_assert(_Old < _New, "sign_extend: _Old should be less than _New");
|
static_assert(_Old < _New, "sign_extend: _Old should be less than _New");
|
||||||
struct { max_ssize_t _M_data : _Old; } tmp;
|
struct {
|
||||||
|
max_ssize_t _M_data : _Old;
|
||||||
|
} tmp;
|
||||||
return Bit<_New>(tmp._M_data = val);
|
return Bit<_New>(tmp._M_data = val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +28,9 @@ constexpr auto sign_extend(const _Tp & val) {
|
|||||||
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
||||||
constexpr auto zero_extend(max_size_t val) {
|
constexpr auto zero_extend(max_size_t val) {
|
||||||
static_assert(_Old < _New, "zero_extend: _Old should be less than _New");
|
static_assert(_Old < _New, "zero_extend: _Old should be less than _New");
|
||||||
struct { max_size_t _M_data : _Old; } tmp;
|
struct {
|
||||||
|
max_size_t _M_data : _Old;
|
||||||
|
} tmp;
|
||||||
return Bit<_New>(tmp._M_data = val);
|
return Bit<_New>(tmp._M_data = val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,5 +86,4 @@ constexpr auto Bit<_Nm>::slice(std::size_t pos) const -> Bit <_Len> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace dark
|
} // namespace dark
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <limits>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
@ -30,8 +30,7 @@ concept implicit_convertible_to = requires(_From &a, func_t <_To> b) {
|
|||||||
|
|
||||||
template<typename _From, typename _To>
|
template<typename _From, typename _To>
|
||||||
concept explicit_convertible_to =
|
concept explicit_convertible_to =
|
||||||
!implicit_convertible_to <_From, _To>
|
!implicit_convertible_to<_From, _To> && std::constructible_from<_To, _From>;
|
||||||
&& std::constructible_from <_To, _From>;
|
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
concept has_length = requires { { +_Tp::_Bit_Len } -> std::same_as <std::size_t>; };
|
concept has_length = requires { { +_Tp::_Bit_Len } -> std::same_as <std::size_t>; };
|
||||||
@ -44,8 +43,7 @@ concept int_type = !has_length <_Tp> && implicit_convertible_to <_Tp, max_size_t
|
|||||||
|
|
||||||
template<typename _Lhs, typename _Rhs>
|
template<typename _Lhs, typename _Rhs>
|
||||||
concept bit_match =
|
concept bit_match =
|
||||||
(bit_type <_Lhs> && bit_type <_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len)
|
(bit_type<_Lhs> && bit_type<_Rhs> && _Lhs::_Bit_Len == _Rhs::_Bit_Len) || (int_type<_Lhs> || int_type<_Rhs>);
|
||||||
|| (int_type <_Lhs> || int_type <_Rhs>);
|
|
||||||
|
|
||||||
template<typename _Tp, std::size_t _Len>
|
template<typename _Tp, std::size_t _Len>
|
||||||
concept bit_convertible =
|
concept bit_convertible =
|
||||||
|
@ -51,6 +51,7 @@ struct DebugValue {
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
private:
|
private:
|
||||||
_Tp _M_value = _Default;
|
_Tp _M_value = _Default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto get_value() const { return this->_M_value; }
|
auto get_value() const { return this->_M_value; }
|
||||||
auto set_value(_Tp value) { this->_M_value = value; }
|
auto set_value(_Tp value) { this->_M_value = value; }
|
||||||
@ -61,7 +62,10 @@ struct DebugValue {
|
|||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
explicit operator _Tp() const { return this->get_value(); }
|
explicit operator _Tp() const { return this->get_value(); }
|
||||||
DebugValue &operator=(_Tp value) { this->set_value(value); return *this; }
|
DebugValue &operator=(_Tp value) {
|
||||||
|
this->set_value(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dark::debug
|
} // namespace dark::debug
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
|
using dark::concepts::bit_match;
|
||||||
using dark::concepts::bit_type;
|
using dark::concepts::bit_type;
|
||||||
using dark::concepts::int_type;
|
using dark::concepts::int_type;
|
||||||
using dark::concepts::bit_match;
|
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
constexpr auto cast(const _Tp &value) {
|
constexpr auto cast(const _Tp &value) {
|
||||||
@ -17,7 +17,8 @@ consteval auto get_common_length() -> std::size_t {
|
|||||||
static_assert(bit_match<_Tp, _Up>);
|
static_assert(bit_match<_Tp, _Up>);
|
||||||
if constexpr (bit_type<_Tp>) {
|
if constexpr (bit_type<_Tp>) {
|
||||||
return _Tp::_Bit_Len;
|
return _Tp::_Bit_Len;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
static_assert(bit_type<_Up>, "Invalid common length");
|
static_assert(bit_type<_Up>, "Invalid common length");
|
||||||
return _Up::_Bit_Len;
|
return _Up::_Bit_Len;
|
||||||
}
|
}
|
||||||
|
@ -1,79 +1,102 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <tuple>
|
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
namespace dark::reflect {
|
namespace dark::reflect {
|
||||||
|
|
||||||
/* A init helper to get the size of a struct. */
|
/* A init helper to get the size of a struct. */
|
||||||
struct init_helper { template <typename _Tp> operator _Tp(); };
|
struct init_helper {
|
||||||
|
template<typename _Tp>
|
||||||
|
operator _Tp();
|
||||||
|
};
|
||||||
|
|
||||||
/* A size helper to get the size of a struct. */
|
/* A size helper to get the size of a struct. */
|
||||||
template <typename _Tp> requires std::is_aggregate_v <_Tp>
|
template<typename _Tp>
|
||||||
|
requires std::is_aggregate_v<_Tp>
|
||||||
inline consteval auto member_size_aux(auto &&...args) -> std::size_t {
|
inline consteval auto member_size_aux(auto &&...args) -> std::size_t {
|
||||||
constexpr std::size_t size = sizeof...(args);
|
constexpr std::size_t size = sizeof...(args);
|
||||||
constexpr std::size_t maximum = 114;
|
constexpr std::size_t maximum = 114;
|
||||||
if constexpr (size > maximum) {
|
if constexpr (size > maximum) {
|
||||||
static_assert(sizeof(_Tp) == 0, "The struct has too many members.");
|
static_assert(sizeof(_Tp) == 0, "The struct has too many members.");
|
||||||
} else if constexpr (!requires {_Tp { args... }; }) {
|
}
|
||||||
|
else if constexpr (!requires { _Tp{args...}; }) {
|
||||||
return size - 1;
|
return size - 1;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return member_size_aux<_Tp>(args..., init_helper{});
|
return member_size_aux<_Tp>(args..., init_helper{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the member size for a aggregate type without base. */
|
/* Return the member size for a aggregate type without base. */
|
||||||
template <typename _Tp> requires std::is_aggregate_v <_Tp>
|
template<typename _Tp>
|
||||||
|
requires std::is_aggregate_v<_Tp>
|
||||||
inline consteval auto member_size(_Tp &) -> std::size_t { return member_size_aux<_Tp>(); }
|
inline consteval auto member_size(_Tp &) -> std::size_t { return member_size_aux<_Tp>(); }
|
||||||
|
|
||||||
template <typename _Tp> requires std::is_aggregate_v <_Tp>
|
template<typename _Tp>
|
||||||
|
requires std::is_aggregate_v<_Tp>
|
||||||
inline consteval auto member_size() -> std::size_t { return member_size_aux<_Tp>(); }
|
inline consteval auto member_size() -> std::size_t { return member_size_aux<_Tp>(); }
|
||||||
|
|
||||||
template <typename _Tp> requires std::is_aggregate_v <_Tp>
|
template<typename _Tp>
|
||||||
|
requires std::is_aggregate_v<_Tp>
|
||||||
auto tuplify(_Tp &value) {
|
auto tuplify(_Tp &value) {
|
||||||
constexpr auto size = member_size<_Tp>();
|
constexpr auto size = member_size<_Tp>();
|
||||||
if constexpr (size == 1) {
|
if constexpr (size == 1) {
|
||||||
auto &[x0] = value;
|
auto &[x0] = value;
|
||||||
return std::forward_as_tuple(x0);
|
return std::forward_as_tuple(x0);
|
||||||
} else if constexpr (size == 2) {
|
}
|
||||||
|
else if constexpr (size == 2) {
|
||||||
auto &[x0, x1] = value;
|
auto &[x0, x1] = value;
|
||||||
return std::forward_as_tuple(x0, x1);
|
return std::forward_as_tuple(x0, x1);
|
||||||
} else if constexpr (size == 3) {
|
}
|
||||||
|
else if constexpr (size == 3) {
|
||||||
auto &[x0, x1, x2] = value;
|
auto &[x0, x1, x2] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2);
|
return std::forward_as_tuple(x0, x1, x2);
|
||||||
} else if constexpr (size == 4) {
|
}
|
||||||
|
else if constexpr (size == 4) {
|
||||||
auto &[x0, x1, x2, x3] = value;
|
auto &[x0, x1, x2, x3] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2, x3);
|
return std::forward_as_tuple(x0, x1, x2, x3);
|
||||||
} else if constexpr (size == 5) {
|
}
|
||||||
|
else if constexpr (size == 5) {
|
||||||
auto &[x0, x1, x2, x3, x4] = value;
|
auto &[x0, x1, x2, x3, x4] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2, x3, x4);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4);
|
||||||
} else if constexpr (size == 6) {
|
}
|
||||||
|
else if constexpr (size == 6) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5] = value;
|
auto &[x0, x1, x2, x3, x4, x5] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5);
|
||||||
} else if constexpr (size == 7) {
|
}
|
||||||
|
else if constexpr (size == 7) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6] = value;
|
auto &[x0, x1, x2, x3, x4, x5, x6] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6);
|
||||||
} else if constexpr (size == 8) {
|
}
|
||||||
|
else if constexpr (size == 8) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7] = value;
|
auto &[x0, x1, x2, x3, x4, x5, x6, x7] = value;
|
||||||
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7);
|
||||||
} else if constexpr (size == 9) {
|
}
|
||||||
|
else if constexpr (size == 9) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8);
|
||||||
} else if constexpr (size == 10) {
|
}
|
||||||
|
else if constexpr (size == 10) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9);
|
||||||
} else if constexpr (size == 11) {
|
}
|
||||||
|
else if constexpr (size == 11) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
|
||||||
} else if constexpr (size == 12) {
|
}
|
||||||
|
else if constexpr (size == 12) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11);
|
||||||
} else if constexpr (size == 13) {
|
}
|
||||||
|
else if constexpr (size == 13) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12);
|
||||||
} else if constexpr (size == 14) {
|
}
|
||||||
|
else if constexpr (size == 14) {
|
||||||
auto &[x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13] = value;
|
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);
|
return std::forward_as_tuple(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
static_assert(sizeof(_Tp) == 0, "The struct has too many members.");
|
static_assert(sizeof(_Tp) == 0, "The struct has too many members.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "debug.h"
|
|
||||||
#include "concept.h"
|
#include "concept.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
|
@ -9,7 +9,8 @@ struct Visitor {
|
|||||||
static constexpr bool is_syncable_v =
|
static constexpr bool is_syncable_v =
|
||||||
requires(_Tp &val) { { val.sync() } -> std::same_as<void>; };
|
requires(_Tp &val) { { val.sync() } -> std::same_as<void>; };
|
||||||
|
|
||||||
template <typename _Tp> requires is_syncable_v<_Tp>
|
template<typename _Tp>
|
||||||
|
requires is_syncable_v<_Tp>
|
||||||
static void sync(_Tp &val) { val.sync(); }
|
static void sync(_Tp &val) { val.sync(); }
|
||||||
|
|
||||||
template<typename _Tp, typename _Base>
|
template<typename _Tp, typename _Base>
|
||||||
@ -43,18 +44,23 @@ template <typename _Tp>
|
|||||||
inline void sync_member(_Tp &value) {
|
inline void sync_member(_Tp &value) {
|
||||||
if constexpr (std::is_const_v<_Tp>) {
|
if constexpr (std::is_const_v<_Tp>) {
|
||||||
/* Do nothing! Constant members need no synchronization! */
|
/* Do nothing! Constant members need no synchronization! */
|
||||||
} else if constexpr (is_std_array_v<_Tp>) {
|
}
|
||||||
|
else if constexpr (is_std_array_v<_Tp>) {
|
||||||
for (auto &member: value) sync_member(member);
|
for (auto &member: value) sync_member(member);
|
||||||
} else if constexpr (Visitor::is_syncable_v<_Tp>) {
|
}
|
||||||
|
else if constexpr (Visitor::is_syncable_v<_Tp>) {
|
||||||
Visitor::sync(value);
|
Visitor::sync(value);
|
||||||
} else if constexpr (has_valid_tag<_Tp>) {
|
}
|
||||||
|
else if constexpr (has_valid_tag<_Tp>) {
|
||||||
sync_by_tag(value, typename _Tp::Tags{});
|
sync_by_tag(value, typename _Tp::Tags{});
|
||||||
} else if constexpr (std::is_aggregate_v<_Tp>) {
|
}
|
||||||
|
else if constexpr (std::is_aggregate_v<_Tp>) {
|
||||||
auto &&tuple = reflect::tuplify(value);
|
auto &&tuple = reflect::tuplify(value);
|
||||||
std::apply([](auto &...members) { (sync_member(members), ...); }, tuple);
|
std::apply([](auto &...members) { (sync_member(members), ...); }, tuple);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
static_assert(sizeof(_Tp) == 0, "This type is not syncable.");
|
static_assert(sizeof(_Tp) == 0, "This type is not syncable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dark::hardware
|
} // namespace dark
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "bit.h"
|
#include "bit.h"
|
||||||
#include "bit_impl.h"
|
#include "bit_impl.h"
|
||||||
#include "wire.h"
|
#include "operator.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include "synchronize.h"
|
#include "synchronize.h"
|
||||||
#include "operator.h"
|
#include "wire.h"
|
||||||
|
|
||||||
using dark::Bit;
|
using dark::Bit;
|
||||||
using dark::sign_extend;
|
using dark::sign_extend;
|
||||||
using dark::zero_extend;
|
using dark::zero_extend;
|
||||||
|
|
||||||
using dark::Wire;
|
|
||||||
using dark::Register;
|
using dark::Register;
|
||||||
|
using dark::Wire;
|
||||||
|
|
||||||
using dark::SyncTags;
|
|
||||||
using dark::sync_member;
|
using dark::sync_member;
|
||||||
|
using dark::SyncTags;
|
||||||
using dark::Visitor;
|
using dark::Visitor;
|
||||||
|
|
||||||
using dark::max_size_t;
|
using dark::max_size_t;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "debug.h"
|
|
||||||
#include "concept.h"
|
#include "concept.h"
|
||||||
|
#include "debug.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
@ -59,6 +59,7 @@ struct Wire {
|
|||||||
[[no_unique_address]]
|
[[no_unique_address]]
|
||||||
debug::DebugValue<bool, false> _M_assigned;
|
debug::DebugValue<bool, false> _M_assigned;
|
||||||
|
|
||||||
|
private:
|
||||||
void sync() { this->_M_holds = false; }
|
void sync() { this->_M_holds = false; }
|
||||||
|
|
||||||
template<details::WireFunction<_Len> _Fn>
|
template<details::WireFunction<_Len> _Fn>
|
||||||
@ -75,8 +76,7 @@ struct Wire {
|
|||||||
public:
|
public:
|
||||||
static constexpr std::size_t _Bit_Len = _Len;
|
static constexpr std::size_t _Bit_Len = _Len;
|
||||||
|
|
||||||
Wire() :
|
Wire() : _M_func(new details::EmptyWire),
|
||||||
_M_func(new details::EmptyWire),
|
|
||||||
_M_cache(), _M_holds(), _M_assigned() {}
|
_M_cache(), _M_holds(), _M_assigned() {}
|
||||||
|
|
||||||
explicit operator max_size_t() const {
|
explicit operator max_size_t() const {
|
||||||
@ -93,8 +93,7 @@ struct Wire {
|
|||||||
Wire &operator=(const Wire &rhs) = delete;
|
Wire &operator=(const Wire &rhs) = delete;
|
||||||
|
|
||||||
template<details::WireFunction<_Len> _Fn>
|
template<details::WireFunction<_Len> _Fn>
|
||||||
Wire(_Fn &&fn) :
|
Wire(_Fn &&fn) : _M_func(_M_new_func(std::forward<_Fn>(fn))),
|
||||||
_M_func(_M_new_func(std::forward <_Fn> (fn))),
|
|
||||||
_M_cache(), _M_holds(), _M_assigned() {}
|
_M_cache(), _M_holds(), _M_assigned() {}
|
||||||
|
|
||||||
template<details::WireFunction<_Len> _Fn>
|
template<details::WireFunction<_Len> _Fn>
|
||||||
|
Reference in New Issue
Block a user