mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 08:46:45 +08:00
Add nameof & scope_exit
This commit is contained in:
parent
f987e35870
commit
b3d520cd25
43
include/libipc/imp/nameof.h
Normal file
43
include/libipc/imp/nameof.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* \file libimp/nameof.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Gets the name string of a type.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#include "libipc/imp/export.h"
|
||||
#include "libipc/imp/span.h"
|
||||
#include "libipc/imp/detect_plat.h"
|
||||
|
||||
namespace ipc {
|
||||
|
||||
/**
|
||||
* \brief The conventional way to obtain demangled symbol name.
|
||||
* \see https://www.boost.org/doc/libs/1_80_0/libs/core/doc/html/core/demangle.html
|
||||
*
|
||||
* \param name the mangled name
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
IPC_EXPORT std::string demangle(std::string name) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Returns an implementation defined string containing the name of the type.
|
||||
* \see https://en.cppreference.com/w/cpp/types/type_info/name
|
||||
*
|
||||
* \tparam T a type
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
template <typename T>
|
||||
std::string nameof() noexcept {
|
||||
LIBIPC_TRY {
|
||||
return demangle(typeid(T).name());
|
||||
} LIBIPC_CATCH(...) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
77
include/libipc/imp/scope_exit.h
Normal file
77
include/libipc/imp/scope_exit.h
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* \file libimp/scope_exit.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Execute guard function when the enclosing scope exits.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <utility> // std::forward, std::move
|
||||
#include <functional> // std::function
|
||||
#include <type_traits>
|
||||
|
||||
#include "libipc/imp/detect_plat.h"
|
||||
|
||||
namespace ipc {
|
||||
|
||||
template <typename F = std::function<void()>>
|
||||
class scope_exit {
|
||||
F destructor_;
|
||||
mutable bool released_;
|
||||
|
||||
public:
|
||||
template <typename G>
|
||||
explicit scope_exit(G &&destructor) noexcept
|
||||
: destructor_(std::forward<G>(destructor))
|
||||
, released_ (false) {}
|
||||
|
||||
scope_exit(scope_exit &&other) noexcept
|
||||
: destructor_(std::move(other.destructor_))
|
||||
, released_ (std::exchange(other.released_, true)) /*release rhs*/ {}
|
||||
|
||||
scope_exit &operator=(scope_exit &&other) noexcept {
|
||||
destructor_ = std::move(other.destructor_);
|
||||
released_ = std::exchange(other.released_, true);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~scope_exit() noexcept {
|
||||
if (!released_) destructor_();
|
||||
}
|
||||
|
||||
void release() const noexcept {
|
||||
released_ = true;
|
||||
}
|
||||
|
||||
void do_exit() noexcept {
|
||||
if (released_) return;
|
||||
destructor_();
|
||||
released_ = true;
|
||||
}
|
||||
|
||||
void swap(scope_exit &other) noexcept {
|
||||
std::swap(destructor_, other.destructor_);
|
||||
std::swap(released_ , other.released_);
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Creates a scope_exit object.
|
||||
template <typename F>
|
||||
auto make_scope_exit(F &&destructor) noexcept {
|
||||
return scope_exit<std::decay_t<F>>(std::forward<F>(destructor));
|
||||
}
|
||||
|
||||
namespace detail_scope_exit {
|
||||
|
||||
struct scope_exit_helper {
|
||||
template <typename F>
|
||||
auto operator=(F &&f) const noexcept {
|
||||
return make_scope_exit(std::forward<F>(f));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail_scope_exit
|
||||
|
||||
#define LIBIPC_SCOPE_EXIT($VAL) \
|
||||
LIBIPC_UNUSED auto $VAL = ::ipc::detail_scope_exit::scope_exit_helper{}
|
||||
|
||||
} // namespace ipc
|
||||
@ -5,6 +5,8 @@ set (PACKAGE_VERSION 1.3.0)
|
||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc SRC_FILES)
|
||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc/sync SRC_FILES)
|
||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc/platform SRC_FILES)
|
||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc/imp SRC_FILES)
|
||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc/mem SRC_FILES)
|
||||
|
||||
file(GLOB HEAD_FILES
|
||||
${LIBIPC_PROJECT_DIR}/include/libipc/*.h
|
||||
|
||||
7
src/libipc/imp/nameof.cpp
Normal file
7
src/libipc/imp/nameof.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
#include "libipc/imp/detect_plat.h"
|
||||
#if defined(LIBIPC_CC_GNUC)
|
||||
# include "libipc/platform/gnuc/demangle.h"
|
||||
#else
|
||||
# include "libipc/platform/win/demangle.h"
|
||||
#endif
|
||||
43
src/libipc/platform/gnuc/demangle.h
Normal file
43
src/libipc/platform/gnuc/demangle.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* \file libipc/platform/gnuc/demangle.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cxxabi.h> // abi::__cxa_demangle
|
||||
#include <cstdlib> // std::malloc
|
||||
|
||||
#include "libipc/imp/nameof.h"
|
||||
#include "libipc/imp/scope_exit.h"
|
||||
#include "libipc/imp/detect_plat.h"
|
||||
|
||||
namespace ipc {
|
||||
|
||||
/**
|
||||
* \brief The conventional way to obtain demangled symbol name.
|
||||
* \see https://www.boost.org/doc/libs/1_80_0/libs/core/doc/html/core/demangle.html
|
||||
*
|
||||
* \param name the mangled name
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
std::string demangle(std::string name) noexcept {
|
||||
/// \see https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
|
||||
std::size_t sz = name.size() + 1;
|
||||
char *buffer = static_cast<char *>(std::malloc(sz));
|
||||
int status = 0;
|
||||
char *realname = abi::__cxa_demangle(name.data(), buffer, &sz, &status);
|
||||
if (realname == nullptr) {
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
LIBIPC_SCOPE_EXIT(guard) = [realname] {
|
||||
std::free(realname);
|
||||
};
|
||||
LIBIPC_TRY {
|
||||
return std::move(name.assign(realname, sz));
|
||||
} LIBIPC_CATCH(...) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
15
src/libipc/platform/win/demangle.h
Normal file
15
src/libipc/platform/win/demangle.h
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* \file libipc/platform/win/demangle.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "libipc/imp/nameof.h"
|
||||
|
||||
namespace ipc {
|
||||
|
||||
std::string demangle(std::string name) noexcept {
|
||||
return std::move(name);
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
Loading…
x
Reference in New Issue
Block a user