Merge branch 'master' of code.uocat.com:tqcq/sled
This commit is contained in:
commit
bd0f7bd208
@ -70,11 +70,6 @@ target_sources(
|
|||||||
# set(BUILD_WITH_STATIC_RUNTIME_LIBS ON) set(BUILD_WITH_DOCUMENTATION OFF)
|
# set(BUILD_WITH_STATIC_RUNTIME_LIBS ON) set(BUILD_WITH_DOCUMENTATION OFF)
|
||||||
# add_subdirectory(3party/rttr EXCLUDE_FROM_ALL)
|
# add_subdirectory(3party/rttr EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
target_include_directories(
|
|
||||||
sled
|
|
||||||
PUBLIC include
|
|
||||||
PRIVATE src)
|
|
||||||
|
|
||||||
target_link_libraries(sled PUBLIC rpc_core fmt marl protobuf::libprotobuf)
|
target_link_libraries(sled PUBLIC rpc_core fmt marl protobuf::libprotobuf)
|
||||||
|
|
||||||
if(SLED_BUILD_BENCHMARK)
|
if(SLED_BUILD_BENCHMARK)
|
||||||
@ -100,6 +95,7 @@ if(SLED_BUILD_TESTS)
|
|||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(googletest)
|
FetchContent_MakeAvailable(googletest)
|
||||||
add_executable(sled_tests
|
add_executable(sled_tests
|
||||||
|
src/any_test.cc
|
||||||
src/filesystem/path_test.cc
|
src/filesystem/path_test.cc
|
||||||
src/strings/base64_test.cc
|
src/strings/base64_test.cc
|
||||||
src/cleanup_test.cc
|
src/cleanup_test.cc
|
||||||
|
@ -332,6 +332,98 @@ any_cast(any &&operand)
|
|||||||
return any_cast<ValueType>(operand);
|
return any_cast<ValueType>(operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Any final {
|
||||||
|
public:
|
||||||
|
inline Any() {}
|
||||||
|
|
||||||
|
inline Any(const Any &other) : value_(other.value_) {}
|
||||||
|
|
||||||
|
inline Any(Any &&other) noexcept : value_(std::move(other.value_)) {}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline Any(const ValueType &value) : value_(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline Any(
|
||||||
|
ValueType &&value,
|
||||||
|
typename std::enable_if<!std::is_same<Any &, ValueType>::value>::type
|
||||||
|
* = 0,
|
||||||
|
typename std::enable_if<!std::is_const<ValueType>::value>::type * = 0)
|
||||||
|
: value_(std::forward<ValueType &&>(value))
|
||||||
|
{}
|
||||||
|
|
||||||
|
// ~Any() noexcept {}
|
||||||
|
|
||||||
|
Any &operator=(const Any &rhs)
|
||||||
|
{
|
||||||
|
Any(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Any &operator=(Any &&rhs) noexcept
|
||||||
|
{
|
||||||
|
rhs.swap(*this);
|
||||||
|
Any().swap(rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
Any &operator=(ValueType &&rhs)
|
||||||
|
{
|
||||||
|
Any(static_cast<ValueType &&>(rhs)).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline auto Cast() const -> ValueType const
|
||||||
|
{
|
||||||
|
return any_cast<ValueType>(value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType Cast() const &&
|
||||||
|
{
|
||||||
|
return any_cast<ValueType>(value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename U = ValueType>
|
||||||
|
inline auto CastOr(U &&default_value) const -> ValueType
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return any_cast<ValueType>(value_);
|
||||||
|
} catch (const bad_any_cast &e) {
|
||||||
|
return static_cast<ValueType>(default_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType, typename U = ValueType>
|
||||||
|
inline auto CastOr(U &&default_value) -> ValueType
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return any_cast<ValueType>(value_);
|
||||||
|
} catch (const bad_any_cast &e) {
|
||||||
|
return static_cast<ValueType>(default_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() noexcept { Any().swap(*this); }
|
||||||
|
|
||||||
|
bool HasValue() const noexcept { return value_.has_value(); }
|
||||||
|
|
||||||
|
const std::type_info &Type() const noexcept { return value_.type(); }
|
||||||
|
|
||||||
|
Any &swap(Any &rhs) noexcept
|
||||||
|
{
|
||||||
|
std::swap(value_, rhs.value_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
any value_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
|
||||||
#endif /* SLED_ANY_H */
|
#endif /* SLED_ANY_H */
|
||||||
|
41
include/sled/lang/attributes.h
Normal file
41
include/sled/lang/attributes.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef SLED_LANG_ATTRIBUTES_H
|
||||||
|
#define SLED_LANG_ATTRIBUTES_H
|
||||||
|
|
||||||
|
#define SLED_DEPRECATED() __attribute__((deprecated))
|
||||||
|
#if defined(__GNUC__) && defined(__SUPPORT_TS_ANNOTATION__) && !defined(SWIG)
|
||||||
|
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||||
|
#elif defined(__clang__)
|
||||||
|
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||||
|
#else
|
||||||
|
#define THREAD_ANNOTATION_ATTRIBUTE__(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GUARDED_BY)
|
||||||
|
#undef GUARDED_BY
|
||||||
|
#endif
|
||||||
|
#define GUARDED_BY(x) __attribute__((guarded_by(x)))
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define EXCLUSIVE_LOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define UNLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
|
||||||
|
|
||||||
|
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock(__VA_ARGS__))
|
||||||
|
#define EXCLUSIVE_LOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock(__VA_ARGS__))
|
||||||
|
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock(__VA_ARGS__))
|
||||||
|
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(point_to_guarded_by(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif// SLED_LANG_ATTRIBUTES_H
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "sled/ref_count.h"
|
#include "sled/ref_count.h"
|
||||||
#include "sled/ref_counter.h"
|
#include "sled/ref_counter.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace sled {
|
namespace sled {
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
ConditionVariable cv_;
|
ConditionVariable cv_;
|
||||||
const bool is_manual_reset_;
|
const bool is_manual_reset_;
|
||||||
bool event_status_;
|
bool event_status_ GUARDED_BY(mutex_);
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "marl/conditionvariable.h"
|
|
||||||
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
|
#ifndef SLED_SYNCHRONIZATION_MUTEX_H
|
||||||
#define SLED_SYNCHRONIZATION_MUTEX_H
|
#define SLED_SYNCHRONIZATION_MUTEX_H
|
||||||
|
|
||||||
|
#include "marl/conditionvariable.h"
|
||||||
|
#include "sled/lang/attributes.h"
|
||||||
#include "sled/units/time_delta.h"
|
#include "sled/units/time_delta.h"
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
@ -59,13 +60,13 @@ public:
|
|||||||
RecursiveMutex(const RecursiveMutex &) = delete;
|
RecursiveMutex(const RecursiveMutex &) = delete;
|
||||||
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
|
RecursiveMutex &operator=(const RecursiveMutex &) = delete;
|
||||||
|
|
||||||
inline void Lock() { impl_.lock(); }
|
inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { impl_.lock(); }
|
||||||
|
|
||||||
inline bool TryLock() { return impl_.try_lock(); }
|
inline bool TryLock() { return impl_.try_lock(); }
|
||||||
|
|
||||||
inline void AssertHeld() {}
|
inline void AssertHeld() {}
|
||||||
|
|
||||||
inline void Unlock() { impl_.unlock(); }
|
inline void Unlock() UNLOCK_FUNCTION() { impl_.unlock(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex impl_;
|
std::recursive_mutex impl_;
|
||||||
@ -77,32 +78,35 @@ public:
|
|||||||
LockGuard(const LockGuard &) = delete;
|
LockGuard(const LockGuard &) = delete;
|
||||||
LockGuard &operator=(const LockGuard &) = delete;
|
LockGuard &operator=(const LockGuard &) = delete;
|
||||||
|
|
||||||
explicit LockGuard(TLock *lock) : mutex_(lock) { mutex_->Lock(); };
|
explicit LockGuard(TLock *lock) EXCLUSIVE_LOCK_FUNCTION() : mutex_(lock)
|
||||||
|
{
|
||||||
|
mutex_->Lock();
|
||||||
|
};
|
||||||
|
|
||||||
~LockGuard() { mutex_->Unlock(); };
|
~LockGuard() UNLOCK_FUNCTION() { mutex_->Unlock(); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TLock *mutex_;
|
TLock *mutex_;
|
||||||
friend class ConditionVariable;
|
friend class ConditionVariable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MutexGuard final {
|
class MutexLock final {
|
||||||
public:
|
public:
|
||||||
MutexGuard(Mutex *mutex) : lock_(*mutex) {}
|
MutexLock(Mutex *mutex) : lock_(*mutex) {}
|
||||||
|
|
||||||
MutexGuard(const MutexGuard &) = delete;
|
MutexLock(const MutexLock &) = delete;
|
||||||
MutexGuard &operator=(const MutexGuard &) = delete;
|
MutexLock &operator=(const MutexLock &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class ConditionVariable;
|
friend class ConditionVariable;
|
||||||
marl::lock lock_;
|
marl::lock lock_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using MutexLock = MutexGuard;
|
using MutexGuard SLED_DEPRECATED() = MutexLock;
|
||||||
// using MutexGuard = marl::lock;
|
// using MutexGuard = marl::lock;
|
||||||
// using MutexLock = LockGuard<Mutex>;
|
// using MutexLock = LockGuard<Mutex>;
|
||||||
// using MutexGuard = LockGuard<Mutex>;
|
// using MutexGuard = LockGuard<Mutex>;
|
||||||
using RecursiveMutexLock = LockGuard<RecursiveMutex>;
|
using RecursiveMutexLock SLED_DEPRECATED() = LockGuard<RecursiveMutex>;
|
||||||
|
|
||||||
// class MutexLock final {
|
// class MutexLock final {
|
||||||
// public:
|
// public:
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool happended_ = false;
|
bool happended_ GUARDED_BY(mutex_) = false;
|
||||||
Mutex mutex_;
|
Mutex mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,9 +159,9 @@ private:
|
|||||||
void ClearCurrentTaskQueue();
|
void ClearCurrentTaskQueue();
|
||||||
|
|
||||||
mutable Mutex mutex_;
|
mutable Mutex mutex_;
|
||||||
std::queue<std::function<void()>> messages_;
|
std::queue<std::function<void()>> messages_ GUARDED_BY(mutex_);
|
||||||
std::priority_queue<DelayedMessage> delayed_messages_;
|
std::priority_queue<DelayedMessage> delayed_messages_ GUARDED_BY(mutex_);
|
||||||
uint32_t delayed_next_num_;
|
uint32_t delayed_next_num_ GUARDED_BY(mutex_);
|
||||||
bool fInitialized_;
|
bool fInitialized_;
|
||||||
bool fDestroyed_;
|
bool fDestroyed_;
|
||||||
std::atomic<int> stop_;
|
std::atomic<int> stop_;
|
||||||
@ -183,8 +183,9 @@ public:
|
|||||||
|
|
||||||
AutoSocketServerThread(const AutoSocketServerThread &) = delete;
|
AutoSocketServerThread(const AutoSocketServerThread &) = delete;
|
||||||
AutoSocketServerThread &operator=(const AutoSocketServerThread &) = delete;
|
AutoSocketServerThread &operator=(const AutoSocketServerThread &) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread* old_thread_;
|
Thread *old_thread_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}// namespace sled
|
}// namespace sled
|
||||||
|
48
src/any_test.cc
Normal file
48
src/any_test.cc
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <sled/any.h>
|
||||||
|
#include <sled/log/log.h>
|
||||||
|
|
||||||
|
TEST(Any, Assign)
|
||||||
|
{
|
||||||
|
sled::Any any1;
|
||||||
|
sled::Any any2(any1);
|
||||||
|
sled::Any any3(1);
|
||||||
|
sled::Any any4(any3);
|
||||||
|
sled::Any any5 = 1;
|
||||||
|
EXPECT_FALSE(any1.HasValue());
|
||||||
|
EXPECT_FALSE(any2.HasValue());
|
||||||
|
EXPECT_TRUE(any3.HasValue());
|
||||||
|
EXPECT_TRUE(any4.HasValue());
|
||||||
|
EXPECT_TRUE(any5.HasValue());
|
||||||
|
EXPECT_EQ(any3.Cast<int>(), 1);
|
||||||
|
EXPECT_EQ(any4.Cast<int>(), 1);
|
||||||
|
EXPECT_EQ(any5.Cast<int>(), 1);
|
||||||
|
EXPECT_EQ(any3.CastOr<std::string>("def"), "def");
|
||||||
|
EXPECT_EQ(any4.CastOr<std::string>("def"), "def");
|
||||||
|
EXPECT_EQ(any5.CastOr<std::string>("def"), "def");
|
||||||
|
EXPECT_EQ(any3.CastOr<int>(11), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Any, std_swap)
|
||||||
|
{
|
||||||
|
sled::Any a;
|
||||||
|
sled::Any b = 2;
|
||||||
|
EXPECT_FALSE(a.HasValue());
|
||||||
|
EXPECT_TRUE(b.HasValue());
|
||||||
|
std::swap(a, b);
|
||||||
|
EXPECT_TRUE(a.HasValue());
|
||||||
|
EXPECT_FALSE(b.HasValue());
|
||||||
|
EXPECT_EQ(a.Cast<int>(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Any, custom_swap)
|
||||||
|
{
|
||||||
|
sled::Any a;
|
||||||
|
sled::Any b = 2;
|
||||||
|
EXPECT_FALSE(a.HasValue());
|
||||||
|
EXPECT_TRUE(b.HasValue());
|
||||||
|
a.swap(b);
|
||||||
|
EXPECT_TRUE(a.HasValue());
|
||||||
|
EXPECT_FALSE(b.HasValue());
|
||||||
|
EXPECT_EQ(a.Cast<int>(), 2);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user