C++17 niceties

- class template argument deduction lets us write `std::unique_lock
  foo{mutex}` instead of `std::unique_lock<mutex_type> foo{mutex}` which
  makes the `unique_lock` and `shared_lock` functions unnecessary.

- Replace GNU-specific warn_unused_result attribute with C++17-standard
  [[nodiscard]]

- Remove pre-C++17 workaround code for fold expressions, void_t
pull/1263/head
Jason Rhinelander 4 years ago
parent 08a1b74c3b
commit e470a6d73e

@ -484,7 +484,7 @@ llarp_nodedb::LoadAll()
size_t size_t
llarp_nodedb::num_loaded() const llarp_nodedb::num_loaded() const
{ {
auto l = llarp::util::shared_lock(access); std::shared_lock l{access};
return entries.size(); return entries.size();
} }

@ -217,7 +217,7 @@ namespace llarp
bool bool
Profiling::Save(const char* fname) Profiling::Save(const char* fname)
{ {
auto lock = util::shared_lock(m_ProfilesMutex); std::shared_lock lock{m_ProfilesMutex};
size_t sz = (m_Profiles.size() * (RouterProfile::MaxSize + 32 + 8)) + 8; size_t sz = (m_Profiles.size() * (RouterProfile::MaxSize + 32 + 8)) + 8;
std::vector<byte_t> tmp(sz, 0); std::vector<byte_t> tmp(sz, 0);
@ -243,7 +243,7 @@ namespace llarp
bool bool
Profiling::BEncode(llarp_buffer_t* buf) const Profiling::BEncode(llarp_buffer_t* buf) const
{ {
auto lock = util::shared_lock(m_ProfilesMutex); std::shared_lock lock{m_ProfilesMutex};
return BEncodeNoLock(buf); return BEncodeNoLock(buf);
} }

@ -170,7 +170,7 @@ namespace llarp
void void
OutboundSessionMaker::DoEstablish(const RouterID& router) OutboundSessionMaker::DoEstablish(const RouterID& router)
{ {
auto l = util::unique_lock(_mutex); std::unique_lock l{_mutex};
auto itr = pendingSessions.find(router); auto itr = pendingSessions.find(router);
@ -193,7 +193,7 @@ namespace llarp
OutboundSessionMaker::GotRouterContact(const RouterID& router, const RouterContact& rc) OutboundSessionMaker::GotRouterContact(const RouterID& router, const RouterContact& rc)
{ {
{ {
auto l = util::unique_lock(_mutex); std::unique_lock l{_mutex};
// in case other request found RC for this router after this request was // in case other request found RC for this router after this request was
// made // made

@ -150,7 +150,7 @@ namespace llarp
return true; return true;
}; };
auto l = util::shared_lock(nodedb()->access); std::shared_lock l{nodedb()->access};
return pick_router(nodedb()->entries); return pick_router(nodedb()->entries);
} }

@ -10,19 +10,6 @@ namespace llarp
{ {
namespace traits namespace traits
{ {
#ifdef __cpp_lib_void_t
using std::void_t;
#else
/// C++17 void_t backport
template <typename... Ts>
struct void_t_impl
{
using type = void;
};
template <typename... Ts>
using void_t = typename void_t_impl<Ts...>::type;
#endif
/// Represents the empty type /// Represents the empty type
struct Bottom struct Bottom
{ {
@ -46,7 +33,7 @@ namespace llarp
// - has dereference operator // - has dereference operator
// - has arrow operator // - has arrow operator
template <typename T> template <typename T>
struct is_pointy<T, std::conditional_t<false, void_t<decltype(*std::declval<T>())>, void>> struct is_pointy<T, std::conditional_t<false, std::void_t<decltype(*std::declval<T>())>, void>>
: public std::true_type : public std::true_type
{ {
}; };
@ -65,7 +52,7 @@ namespace llarp
T, T,
std::conditional_t< std::conditional_t<
false, false,
void_t< typename T::value_type, std::void_t< typename T::value_type,
typename T::size_type, typename T::size_type,
typename T::iterator, typename T::iterator,
typename T::const_iterator, typename T::const_iterator,

@ -24,10 +24,7 @@ namespace llarp
/// Trim leading and trailing (ascii) whitespace from the given string; /// Trim leading and trailing (ascii) whitespace from the given string;
/// returns a std::string_view of the trimmed part of the string. /// returns a std::string_view of the trimmed part of the string.
#ifdef __GNUG__ [[nodiscard]] std::string_view
[[gnu::warn_unused_result]]
#endif
std::string_view
TrimWhitespace(std::string_view str); TrimWhitespace(std::string_view str);
template <typename... T> template <typename... T>
@ -35,11 +32,7 @@ namespace llarp
stringify(T&&... stuff) stringify(T&&... stuff)
{ {
std::ostringstream o; std::ostringstream o;
#ifdef __cpp_fold_expressions
(o << ... << std::forward<T>(stuff)); (o << ... << std::forward<T>(stuff));
#else
(void)std::initializer_list<int>{(o << std::forward<T>(stuff), 0)...};
#endif
return o.str(); return o.str();
} }

@ -25,7 +25,7 @@ namespace llarp
bool bool
Block() Block()
{ {
std::unique_lock<std::mutex> lock{mutex}; std::unique_lock lock{mutex};
if (pending == 1) if (pending == 1)
{ {
pending = 0; pending = 0;

@ -64,7 +64,7 @@ namespace llarp
void void
ThreadPool::waitThreads() ThreadPool::waitThreads()
{ {
std::unique_lock<std::mutex> lock(m_gateMutex); std::unique_lock lock{m_gateMutex};
m_numThreadsCV.wait(lock, [this] { return allThreadsReady(); }); m_numThreadsCV.wait(lock, [this] { return allThreadsReady(); });
} }
@ -72,7 +72,7 @@ namespace llarp
ThreadPool::releaseThreads() ThreadPool::releaseThreads()
{ {
{ {
std::lock_guard<std::mutex> lock(m_gateMutex); std::lock_guard lock{m_gateMutex};
m_numThreadsReady = 0; m_numThreadsReady = 0;
++m_gateCount; ++m_gateCount;
} }
@ -82,7 +82,7 @@ namespace llarp
void void
ThreadPool::interrupt() ThreadPool::interrupt()
{ {
std::lock_guard<std::mutex> lock(m_gateMutex); std::lock_guard lock{m_gateMutex};
size_t count = m_idleThreads; size_t count = m_idleThreads;
@ -96,14 +96,14 @@ namespace llarp
ThreadPool::worker() ThreadPool::worker()
{ {
// Lock will be valid until the end of the statement // Lock will be valid until the end of the statement
size_t gateCount = (std::lock_guard<std::mutex>(m_gateMutex), m_gateCount); size_t gateCount = (std::lock_guard{m_gateMutex}, m_gateCount);
util::SetThreadName(m_name); util::SetThreadName(m_name);
for (;;) for (;;)
{ {
{ {
std::unique_lock<std::mutex> lock(m_gateMutex); std::unique_lock lock{m_gateMutex};
++m_numThreadsReady; ++m_numThreadsReady;
m_numThreadsCV.notify_one(); m_numThreadsCV.notify_one();

@ -96,45 +96,14 @@ namespace llarp
/// Basic RAII lock type for the default mutex type. /// Basic RAII lock type for the default mutex type.
using Lock = std::lock_guard<Mutex>; using Lock = std::lock_guard<Mutex>;
/// Returns a unique lock around the given lockable (typically a mutex)
/// which gives exclusive control and is unlockable/relockable. Any extra
/// argument (e.g. std::defer_lock) is forwarded to the unique_lock
/// constructor.
template <typename Mutex, typename... Args>
#ifdef __GNUG__
[[gnu::warn_unused_result]]
#endif
std::unique_lock<Mutex>
unique_lock(Mutex& lockable, Args&&... args)
{
return std::unique_lock<Mutex>(lockable, std::forward<Args>(args)...);
}
/// Returns a shared lock around the given lockable (typically a mutex)
/// which gives "reader" access (i.e. which can be shared with other reader
/// locks but not unique locks). Any extra argument (e.g. std::defer_lock)
/// is forwarded to the std::shared_lock constructor.
template <typename Mutex, typename... Args>
#ifdef __GNUG__
[[gnu::warn_unused_result]]
#endif
std::shared_lock<Mutex>
shared_lock(Mutex& lockable, Args&&... args)
{
return std::shared_lock<Mutex>(lockable, std::forward<Args>(args)...);
}
/// Obtains multiple unique locks simultaneously and atomically. Returns a /// Obtains multiple unique locks simultaneously and atomically. Returns a
/// tuple of all the held locks. /// tuple of all the held locks.
template <typename... Mutex> template <typename... Mutex>
#ifdef __GNUG__ [[nodiscard]] auto
[[gnu::warn_unused_result]]
#endif
std::tuple<std::unique_lock<Mutex>...>
unique_locks(Mutex&... lockables) unique_locks(Mutex&... lockables)
{ {
std::lock(lockables...); std::lock(lockables...);
return std::make_tuple(std::unique_lock<Mutex>(lockables, std::adopt_lock)...); return std::make_tuple(std::unique_lock{lockables, std::adopt_lock}...);
} }
class Semaphore class Semaphore
@ -162,7 +131,7 @@ namespace llarp
void void
wait() EXCLUDES(m_mutex) wait() EXCLUDES(m_mutex)
{ {
auto lock = unique_lock(m_mutex); std::unique_lock lock{m_mutex};
m_cv.wait(lock, [this] { return m_count > 0; }); m_cv.wait(lock, [this] { return m_count > 0; });
m_count--; m_count--;
} }
@ -170,7 +139,7 @@ namespace llarp
bool bool
waitFor(std::chrono::microseconds timeout) EXCLUDES(m_mutex) waitFor(std::chrono::microseconds timeout) EXCLUDES(m_mutex)
{ {
auto lock = unique_lock(m_mutex); std::unique_lock lock{m_mutex};
if (!m_cv.wait_for(lock, timeout, [this] { return m_count > 0; })) if (!m_cv.wait_for(lock, timeout, [this] { return m_count > 0; }))
return false; return false;

Loading…
Cancel
Save