2#ifndef INCLUDED_VARIABLE_H_
3#define INCLUDED_VARIABLE_H_
58 }
else if (text.compare(
"*") == 0) {
60 }
else if (text.compare(
"*^") == 0) {
62 }
else if (text.compare(
"&") == 0) {
64 }
else if (text.compare(
"&^") == 0) {
66 }
else if (text.compare(
"&?") == 0) {
68 }
else if (text.compare(
"&?^") == 0) {
70 }
else if (text.compare(
"&*") == 0) {
72 }
else if (text.compare(
"&*^") == 0) {
74 }
else if (text.compare(
"&&") == 0) {
76 }
else if (text.compare(
"&&^") == 0) {
79 LOG_RUNTIME(
"Unknown reference type '%s'!", text.begin());
125 LOG_RUNTIME(
"Unknown reference type code! (%d)",
static_cast<int> (type));
146 mutable std::variant<std::monostate, std::shared_timed_mutex, std::recursive_timed_mutex>
m_sync;
161 m_sync.emplace<std::shared_timed_mutex>();
163 m_sync.emplace<std::recursive_timed_mutex>();
165 LOG_RUNTIME(
"Unknown synchronization type! (%d)",
static_cast<int> (type));
170 static std::shared_ptr<Sync>
CreateSync(
const std::string_view ref);
183 LOG_RUNTIME(
"Calling a function on another thread!");
186 ASSERT(std::holds_alternative<std::shared_timed_mutex>(
m_sync));
193 ASSERT(std::holds_alternative<std::recursive_timed_mutex>(
m_sync));
204 ASSERT(std::holds_alternative<std::shared_timed_mutex>(
m_sync));
205 std::get<std::shared_timed_mutex> (
m_sync).unlock();
207 ASSERT(std::holds_alternative<std::recursive_timed_mutex>(
m_sync));
208 std::get<std::recursive_timed_mutex>(
m_sync).unlock();
235 const std::string_view message =
"",
236 const std::source_location & location = std::source_location::current());
239 const std::chrono::milliseconds & timeout_duration,
240 const std::string_view message,
const std::source_location & location);
244 inline operator bool()
const {
245 if(std::holds_alternative<Variable *> (
variable)){
246 return std::get<Variable *> (
variable);
247 }
else if(std::holds_alternative<std::shared_ptr<Variable>> (
variable)){
248 return std::get<std::shared_ptr<Variable>>(
variable).get();
250 return std::get<std::shared_ptr<Sync>>(
variable).get() && std::get<std::shared_ptr<Sync>>(
variable)->m_data;
254 if(std::holds_alternative<Variable *> (
variable)){
256 return *std::get<Variable *> (
variable);
257 }
else if(std::holds_alternative<std::shared_ptr<Variable>> (
variable)){
259 return *std::get<std::shared_ptr<Variable>> (
variable);
263 return *(std::get<std::shared_ptr<Sync>>(
variable))->m_data;
267 if(std::holds_alternative<Variable *> (
variable)){
269 return *std::get<Variable *> (
variable);
270 }
else if(std::holds_alternative<std::shared_ptr<Variable>> (
variable)){
272 return *std::get<std::shared_ptr<Variable>> (
variable);
276 return *std::get<std::shared_ptr<Sync>>(
variable)->m_data;
290 template<
typename R,
typename... Args>
297 push_back(
reinterpret_cast<void *
> (func));
301 for (
auto func : list) {
302 push_back(
reinterpret_cast<void *
> (func));
313 push_back(
reinterpret_cast<void *
> (func));
318 for (
auto it = rbegin(); it != rend(); it++) {
319 if (
reinterpret_cast<void *
> (current) == *it) {
349#define DEFINE_OPERATOR(name) static OperatorType name; \
350 static Variable& __ ## name ## __(Variable &self, const Variable &other)
368#undef DEFINE_OPERATOR
379 std::shared_ptr<Variable>
data;
393 typedef std::variant< std::monostate,
399 int64_t, double, std::string, std::wstring,
Rational
403#define VARIABLE_TYPES(_) \
418#define DEFINE_ENUM(name, value) name = static_cast<uint8_t>(value),
423#define MAKE_TYPE_NAME(type_name) type_name
426#define DEFINE_CASE(name, _) \
427 case VariableCase:: name : \
428 return MAKE_TYPE_NAME(":" #name);
434 LOG_RUNTIME(
"UNKNOWN VariableVariant index %d",
static_cast<int> (index));
444 static_assert(std::is_same_v<std::monostate, std::variant_alternative_t < static_cast<size_t> (
VariableCase::EMPTY), VariableVariant>>);
445 static_assert(std::is_same_v<VariableShared, std::variant_alternative_t < static_cast<size_t> (
VariableCase::SHARED), VariableVariant>>);
446 static_assert(std::is_same_v<VariableWeak, std::variant_alternative_t < static_cast<size_t> (
VariableCase::WEAK), VariableVariant>>);
447 static_assert(std::is_same_v<VariableTaken, std::variant_alternative_t < static_cast<size_t> (
VariableCase::TAKEN), VariableVariant>>);
449 static_assert(std::is_same_v<ObjPtr, std::variant_alternative_t < static_cast<size_t> (
VariableCase::OBJECT), VariableVariant>>);
450 static_assert(std::is_same_v<int64_t, std::variant_alternative_t < static_cast<size_t> (
VariableCase::INTEGER), VariableVariant>>);
451 static_assert(std::is_same_v<double, std::variant_alternative_t < static_cast<size_t> (
VariableCase::DOUBLE), VariableVariant>>);
452 static_assert(std::is_same_v<std::string, std::variant_alternative_t < static_cast<size_t> (
VariableCase::STRING), VariableVariant>>);
453 static_assert(std::is_same_v<std::wstring, std::variant_alternative_t < static_cast<size_t> (
VariableCase::WSTRING), VariableVariant>>);
454 static_assert(std::is_same_v<Rational, std::variant_alternative_t < static_cast<size_t> (
VariableCase::RATIONAL), VariableVariant>>);
459 template<
typename T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type
514 return std::make_shared<Variable>(std::monostate());
546 template <class T, typename = typename std::enable_if<!is_shared_ptr<decltype(std::declval<T>())>::value>::type>
550 template <typename T, typename = typename std::enable_if<!is_shared_ptr<decltype(std::declval<T>())>::value>::type>
555 template <typename T, typename = typename std::enable_if<!is_shared_ptr<decltype(std::declval<T>())>::value>::type>
592 return std::holds_alternative<std::monostate>(*
this);
598 (std::holds_alternative<VariableShared> (*
this) && !std::get<VariableShared>(*this).sync);
602 return std::holds_alternative<VariableShared> (*
this) ||
603 std::holds_alternative<VariableTaken> (*
this) ||
604 std::holds_alternative<VariableWeak> (*
this);
611 const std::string_view message =
"",
const std::source_location location = std::source_location::current())
const {
612 return VariableTaken(*
this, edit_mode, timeout_duration, message, location);
639 explicit inline operator bool()
const {
643#define PLACE_RANGE_CHECK_VALUE(itype, utype)\
644 explicit inline operator itype() const { \
645 int64_t result = GetValueAsInteger(); \
646 if (result > std::numeric_limits<itype>::max() || result < std::numeric_limits<itype>::lowest()) { \
647 LOG_RUNTIME("Value '%s' is out of range of the casting type %s!", toString().c_str(), #itype); \
651 explicit inline operator utype() const { \
652 int64_t result = GetValueAsInteger(); \
653 if (result > std::numeric_limits<utype>::max() || result < 0) { \
654 LOG_RUNTIME("Value '%s' is out of range of the casting type %s!", toString().c_str(), #utype); \
663 explicit inline operator int64_t()
const {
667 explicit inline operator uint64_t()
const {
670 LOG_RUNTIME(
"Value '%s' is out of range of the casting type %s!",
toString().c_str(),
"uint64_t");
676#undef PLACE_RANGE_CHECK_VALUE
696 explicit inline operator std::string()
const {
700 explicit inline operator std::wstring()
const {
704 explicit operator void *()
const {
static constexpr std::chrono::seconds SyncWithoutWait
const std::thread::id m_thread_id
const std::chrono::milliseconds & m_timeout
static std::shared_ptr< Sync > CreateSync(const TermPtr &term)
std::thread::id GetThreadId() const
Sync(RefType type, const std::chrono::milliseconds &timeout_duration=SyncTimeoutDeedlock)
RefType GetRefType() const
static constexpr std::chrono::milliseconds SyncTimeoutDeedlock
bool SyncLock(bool edit_mode=true, const std::chrono::milliseconds &timeout_duration=Sync::SyncTimeoutDeedlock)
std::variant< std::monostate, std::shared_timed_mutex, std::recursive_timed_mutex > m_sync
std::shared_ptr< Variable > m_data
Поле данных для использования в классе VariableTaken, чтобы уменьшить размер класса Variable.
static Variable & __imul_only_numbers__(Variable &self, const Variable &other)
static OperatorType ifloordiv
static VirtualFuncImpl< Variable, const Variable & > copy
static int __eq__(const Variable &self, const Variable &other)
static Variable __clone__(const Variable &clone)
static bool __strict_eq__(const Variable &self, const Variable &other)
static OperatorType itruediv
static VirtualFuncImpl< Variable, const Variable & > clone
static Variable & __iadd_only_numbers__(Variable &self, const Variable &other)
static Variable __copy__(const Variable ©)
static VirtualFuncImpl< bool, const Variable &, const Variable & > strict_eq
VirtualFuncImpl< Variable &, Variable &, const Variable & > OperatorType
static VirtualFuncImpl< int, const Variable &, const Variable & > eq
std::variant< Variable *, std::shared_ptr< Variable >, std::shared_ptr< Sync > > variable
static std::string MakeTimeoutMessage(const Variable &var, bool edit_mode, const std::chrono::milliseconds &timeout_duration, const std::string_view message, const std::source_location &location)
VariableTaken(const Variable &var, bool edit_mode, const std::chrono::milliseconds &timeout_duration=Sync::SyncTimeoutDeedlock, const std::string_view message="", const std::source_location &location=std::source_location::current())
const Variable & operator*() const
VariableTaken & operator=(VariableTaken const &var) noexcept
bool operator<(const Variable &other) const
bool is_floating_type() const
Variable & operator*=(const Variable &other)
bool is_rational_type() const
bool operator>=(const Variable &other) const
const Variable operator-(const Variable &other)
Variable(T value, const TermPtr &&term)
const Variable operator/(const Variable &other)
int64_t GetValueAsInteger() const
Variable & operator%=(const Variable &other)
Variable & operator/=(const Variable &other)
Variable & operator+=(const Variable &other)
double GetValueAsNumber() const
std::wstring & GetValueAsStringWide()
bool operator>(const Variable &other) const
std::string & GetValueAsString()
const Variable operator%(const Variable &other)
static VariablePtr UndefinedPtr()
Variable(T value, const std::string_view ref)
bool is_object_type() const
bool operator==(const Variable &other) const
bool GetValueAsBoolean() const
Variable Take(bool edit_mode=false, const std::chrono::milliseconds &timeout_duration=Sync::SyncTimeoutDeedlock, const std::string_view message="", const std::source_location location=std::source_location::current()) const
ObjPtr GetValueAsObject() const
void * GetValueAsPointer() const
const Variable operator+(const Variable &other)
bool is_undefined() const
bool operator<=(const Variable &other) const
const Variable & operator*() const
const Variable operator*(const Variable &other)
bool is_complex_type() const
std::string toString() const
Rational GetValueAsRational() const
bool is_scalar_type() const
int compare(const Variable &other) const
bool strict_eq(const Variable &other) const
Variable & operator-=(const Variable &other)
static bool isShared(const TermPtr &term)
bool is_string_type() const
Variable Ref(const std::string_view ref) const
bool operator!=(const Variable &other) const
R operator()(Args... args)
VirtualFuncType * parent(VirtualFuncType *current)
R VirtualFuncType(Args... args)
VirtualFuncImpl(std::initializer_list< VirtualFuncType * > list)
VirtualFuncImpl(VirtualFuncType *func)
#define DEFINE_CASE(name)
#define LOG_RUNTIME(format,...)
#define STATIC_ASSERT(expr)
#define ASSERT(condition)
std::weak_ptr< Obj > ObjWeak
std::wstring utf8_decode(const std::string str)
constexpr bool isValidReference(RefType type, RefType test)
constexpr bool isLiteRef(RefType type)
constexpr bool isEditableRef(RefType type)
std::weak_ptr< const Obj > ObjWeakConst
std::variant< std::monostate, VariableShared, VariableWeak, VariableTaken, ObjPtr, int64_t, double, std::string, std::wstring, Rational > VariableVariant
std::shared_ptr< Variable > VariablePtr
std::shared_ptr< Term > TermPtr
std::shared_ptr< Obj > ObjPtr
const char * VariableCaseToString(size_t index)
constexpr RefType RefTypeFromString(const std::string_view text)
std::shared_ptr< const Term > TermPtrConst
std::shared_ptr< const Obj > ObjPtrConst
constexpr bool isLiteSyncRef(RefType type)
std::string utf8_encode(const std::wstring wstr)
constexpr bool isConstRef(RefType type)
bool isHeavyRef(RefType type)
#define PLACE_RANGE_CHECK_VALUE(itype, utype)
std::shared_ptr< Variable > data
std::shared_ptr< Sync > sync
Объект синхронизации доступа к защищённой переменной
std::shared_ptr< Sync > sync
Объект синхронизации доступа к ссылке
std::weak_ptr< Variable > weak
Слабый указатель на данные (не владеющая ссылка)
#define DEFINE_OPERATOR(name)
#define VARIABLE_TYPES(_)