style: use tab replace spaces
every one could change the length of tab but not of space
This commit is contained in:
153
include/wire.h
153
include/wire.h
@ -1,113 +1,112 @@
|
||||
#pragma once
|
||||
#include "debug.h"
|
||||
#include "concept.h"
|
||||
#include "debug.h"
|
||||
#include <memory>
|
||||
|
||||
namespace dark {
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename _Fn, std::size_t _Len>
|
||||
concept WireFunction =
|
||||
concepts::bit_convertible <std::decay_t <std::invoke_result_t <_Fn>>, _Len>;
|
||||
template<typename _Fn, std::size_t _Len>
|
||||
concept WireFunction =
|
||||
concepts::bit_convertible<std::decay_t<std::invoke_result_t<_Fn>>, _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 <std::size_t _Len, WireFunction <_Len> _Fn>
|
||||
struct FuncImpl final : FuncBase {
|
||||
_Fn _M_lambda;
|
||||
template<std::size_t _Len, WireFunction<_Len> _Fn>
|
||||
struct FuncImpl final : FuncBase {
|
||||
_Fn _M_lambda;
|
||||
|
||||
template <typename _Tp>
|
||||
FuncImpl(_Tp &&fn) : _M_lambda(std::forward <_Tp> (fn)) {}
|
||||
template<typename _Tp>
|
||||
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 <std::size_t _Len>
|
||||
template<std::size_t _Len>
|
||||
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 <details::FuncBase>;
|
||||
using _Manage_t = std::unique_ptr<details::FuncBase>;
|
||||
|
||||
_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 <bool, false> _M_assigned;
|
||||
[[no_unique_address]]
|
||||
debug::DebugValue<bool, false> _M_assigned;
|
||||
|
||||
void sync() { this->_M_holds = false; }
|
||||
private:
|
||||
void sync() { this->_M_holds = false; }
|
||||
|
||||
template <details::WireFunction <_Len> _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<details::WireFunction<_Len> _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 <details::WireFunction <_Len> _Fn>
|
||||
Wire(_Fn &&fn) :
|
||||
_M_func(_M_new_func(std::forward <_Fn> (fn))),
|
||||
_M_cache(), _M_holds(), _M_assigned() {}
|
||||
template<details::WireFunction<_Len> _Fn>
|
||||
Wire(_Fn &&fn) : _M_func(_M_new_func(std::forward<_Fn>(fn))),
|
||||
_M_cache(), _M_holds(), _M_assigned() {}
|
||||
|
||||
template <details::WireFunction <_Len> _Fn>
|
||||
Wire &operator=(_Fn &&fn) {
|
||||
return this->assign(std::forward <_Fn> (fn)), *this;
|
||||
}
|
||||
template<details::WireFunction<_Len> _Fn>
|
||||
Wire &operator=(_Fn &&fn) {
|
||||
return this->assign(std::forward<_Fn>(fn)), *this;
|
||||
}
|
||||
|
||||
template <details::WireFunction <_Len> _Fn>
|
||||
void assign(_Fn &&fn) {
|
||||
this->_M_checked_assign();
|
||||
this->_M_func.reset(_M_new_func(std::forward <_Fn> (fn)));
|
||||
this->sync();
|
||||
}
|
||||
template<details::WireFunction<_Len> _Fn>
|
||||
void assign(_Fn &&fn) {
|
||||
this->_M_checked_assign();
|
||||
this->_M_func.reset(_M_new_func(std::forward<_Fn>(fn)));
|
||||
this->sync();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user