mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Add nameof & scope_exit
This commit is contained in:
parent
e5a56f02f1
commit
e5546179e2
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 SRC_FILES)
|
||||||
aux_source_directory(${LIBIPC_PROJECT_DIR}/src/libipc/sync 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/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
|
file(GLOB HEAD_FILES
|
||||||
${LIBIPC_PROJECT_DIR}/include/libipc/*.h
|
${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