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)
|
||||
# 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)
|
||||
|
||||
if(SLED_BUILD_BENCHMARK)
|
||||
@ -100,6 +95,7 @@ if(SLED_BUILD_TESTS)
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
add_executable(sled_tests
|
||||
src/any_test.cc
|
||||
src/filesystem/path_test.cc
|
||||
src/strings/base64_test.cc
|
||||
src/cleanup_test.cc
|
||||
|
@ -332,6 +332,98 @@ any_cast(any &&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
|
||||
|
||||
#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_counter.h"
|
||||
#include <memory>
|
||||
|
||||
namespace sled {
|
||||
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
Mutex mutex_;
|
||||
ConditionVariable cv_;
|
||||
const bool is_manual_reset_;
|
||||
bool event_status_;
|
||||
bool event_status_ GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
}// namespace sled
|
||||
|
@ -5,10 +5,11 @@
|
||||
**/
|
||||
|
||||
#pragma once
|
||||
#include "marl/conditionvariable.h"
|
||||
#ifndef 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 <chrono>
|
||||
#include <condition_variable>
|
||||
@ -59,13 +60,13 @@ public:
|
||||
RecursiveMutex(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 void AssertHeld() {}
|
||||
|
||||
inline void Unlock() { impl_.unlock(); }
|
||||
inline void Unlock() UNLOCK_FUNCTION() { impl_.unlock(); }
|
||||
|
||||
private:
|
||||
std::recursive_mutex impl_;
|
||||
@ -77,32 +78,35 @@ public:
|
||||
LockGuard(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:
|
||||
TLock *mutex_;
|
||||
friend class ConditionVariable;
|
||||
};
|
||||
|
||||
class MutexGuard final {
|
||||
class MutexLock final {
|
||||
public:
|
||||
MutexGuard(Mutex *mutex) : lock_(*mutex) {}
|
||||
MutexLock(Mutex *mutex) : lock_(*mutex) {}
|
||||
|
||||
MutexGuard(const MutexGuard &) = delete;
|
||||
MutexGuard &operator=(const MutexGuard &) = delete;
|
||||
MutexLock(const MutexLock &) = delete;
|
||||
MutexLock &operator=(const MutexLock &) = delete;
|
||||
|
||||
private:
|
||||
friend class ConditionVariable;
|
||||
marl::lock lock_;
|
||||
};
|
||||
|
||||
using MutexLock = MutexGuard;
|
||||
using MutexGuard SLED_DEPRECATED() = MutexLock;
|
||||
// using MutexGuard = marl::lock;
|
||||
// using MutexLock = LockGuard<Mutex>;
|
||||
// using MutexGuard = LockGuard<Mutex>;
|
||||
using RecursiveMutexLock = LockGuard<RecursiveMutex>;
|
||||
using RecursiveMutexLock SLED_DEPRECATED() = LockGuard<RecursiveMutex>;
|
||||
|
||||
// class MutexLock final {
|
||||
// public:
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool happended_ = false;
|
||||
bool happended_ GUARDED_BY(mutex_) = false;
|
||||
Mutex mutex_;
|
||||
};
|
||||
|
||||
|
@ -159,9 +159,9 @@ private:
|
||||
void ClearCurrentTaskQueue();
|
||||
|
||||
mutable Mutex mutex_;
|
||||
std::queue<std::function<void()>> messages_;
|
||||
std::priority_queue<DelayedMessage> delayed_messages_;
|
||||
uint32_t delayed_next_num_;
|
||||
std::queue<std::function<void()>> messages_ GUARDED_BY(mutex_);
|
||||
std::priority_queue<DelayedMessage> delayed_messages_ GUARDED_BY(mutex_);
|
||||
uint32_t delayed_next_num_ GUARDED_BY(mutex_);
|
||||
bool fInitialized_;
|
||||
bool fDestroyed_;
|
||||
std::atomic<int> stop_;
|
||||
@ -183,8 +183,9 @@ public:
|
||||
|
||||
AutoSocketServerThread(const AutoSocketServerThread &) = delete;
|
||||
AutoSocketServerThread &operator=(const AutoSocketServerThread &) = delete;
|
||||
|
||||
private:
|
||||
Thread* old_thread_;
|
||||
Thread *old_thread_;
|
||||
};
|
||||
|
||||
}// 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…
Reference in New Issue
Block a user