mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
upd: comment style
This commit is contained in:
parent
3880639699
commit
424bb73c94
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libconcur/concurrent.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define different policies for concurrent queue.
|
||||
* @date 2022-11-07
|
||||
* \file libconcur/concurrent.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define different policies for concurrent queue.
|
||||
* \date 2022-11-07
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -17,10 +17,10 @@
|
||||
|
||||
LIBCONCUR_NAMESPACE_BEG_
|
||||
|
||||
/// @brief The queue index type.
|
||||
/// \brief The queue index type.
|
||||
using index_t = std::uint32_t;
|
||||
|
||||
/// @brief Multiplicity of the relationship.
|
||||
/// \brief Multiplicity of the relationship.
|
||||
namespace relation {
|
||||
|
||||
class single {};
|
||||
@ -28,7 +28,7 @@ class multi {};
|
||||
|
||||
} // namespace relation
|
||||
|
||||
/// @brief Transmission mode
|
||||
/// \brief Transmission mode
|
||||
namespace trans {
|
||||
|
||||
class unicast {};
|
||||
@ -36,52 +36,52 @@ class broadcast {};
|
||||
|
||||
} // namespace trans
|
||||
|
||||
/// @brief Determines whether type T can be implicitly converted to type U.
|
||||
/// \brief Determines whether type T can be implicitly converted to type U.
|
||||
template <typename T, typename U>
|
||||
using is_convertible = typename std::enable_if<std::is_convertible<T *, U *>::value>::type;
|
||||
|
||||
/// @brief Check whether the context type is valid.
|
||||
/// \brief Check whether the context type is valid.
|
||||
template <typename T>
|
||||
using is_context = decltype(typename std::enable_if<std::is_convertible<decltype(
|
||||
std::declval<T>().valid()), bool>::value>::type(),
|
||||
std::declval<index_t>() % std::declval<T>().circ_size);
|
||||
|
||||
/**
|
||||
* @brief Calculate the corresponding queue position modulo the index value.
|
||||
* \brief Calculate the corresponding queue position modulo the index value.
|
||||
*
|
||||
* @tparam C a context type
|
||||
* @param ctx a context object
|
||||
* @param idx a context array index
|
||||
* @return index_t - a corresponding queue position
|
||||
* \tparam C a context type
|
||||
* \param ctx a context object
|
||||
* \param idx a context array index
|
||||
* \return index_t - a corresponding queue position
|
||||
*/
|
||||
template <typename C, typename = is_context<C>>
|
||||
constexpr index_t trunc_index(C const &ctx, index_t idx) noexcept {
|
||||
/// @remark `circ_size == 2^N` => `idx & (circ_size - 1)`
|
||||
/// \remark `circ_size == 2^N` => `idx & (circ_size - 1)`
|
||||
return ctx.valid() ? (idx % ctx.circ_size) : 0;
|
||||
}
|
||||
|
||||
/// @brief Producer algorithm implementation.
|
||||
/// \brief Producer algorithm implementation.
|
||||
template <typename TransModT, typename RelationT>
|
||||
struct producer;
|
||||
|
||||
/// @brief Consumer algorithm implementation.
|
||||
/// \brief Consumer algorithm implementation.
|
||||
template <typename TransModT, typename RelationT>
|
||||
struct consumer;
|
||||
|
||||
/**
|
||||
* @brief Algorithm definition under unicast transmission model.
|
||||
* \brief Algorithm definition under unicast transmission model.
|
||||
*
|
||||
* @ref A bounded wait-free(almost) zero-copy MPMC queue written in C++11.
|
||||
* \ref A bounded wait-free(almost) zero-copy MPMC queue written in C++11.
|
||||
* Modified from MengRao/WFMPMC.
|
||||
* Copyright (c) 2018. Meng Rao (https://github.com/MengRao/WFMPMC).
|
||||
*/
|
||||
|
||||
/// @brief Single-write producer model implementation.
|
||||
/// \brief Single-write producer model implementation.
|
||||
template <>
|
||||
struct producer<trans::unicast, relation::single> {
|
||||
|
||||
struct context_impl {
|
||||
/// @brief Write index.
|
||||
/// \brief Write index.
|
||||
alignas(cache_line_size) index_t w_idx {0};
|
||||
};
|
||||
|
||||
@ -93,26 +93,26 @@ struct producer<trans::unicast, relation::single> {
|
||||
auto w_cur = trunc_index(ctx, w_idx);
|
||||
auto &elem = elems[w_cur];
|
||||
auto f_ct = elem.get_flag();
|
||||
/// @remark Verify index.
|
||||
/// \remark Verify index.
|
||||
if ((f_ct != state::invalid_value) &&
|
||||
(f_ct != w_idx)) {
|
||||
return false; // full
|
||||
}
|
||||
/// @remark Get a valid index and iterate backwards.
|
||||
/// \remark Get a valid index and iterate backwards.
|
||||
ctx.w_idx += 1;
|
||||
/// @remark Set data & flag.
|
||||
/// \remark Set data & flag.
|
||||
elem.set_data(std::forward<U>(src));
|
||||
elem.set_flag(static_cast<index_t>(~w_idx));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Multi-write producer model implementation.
|
||||
/// \brief Multi-write producer model implementation.
|
||||
template <>
|
||||
struct producer<trans::unicast, relation::multi> {
|
||||
|
||||
struct context_impl {
|
||||
/// @brief Write index.
|
||||
/// \brief Write index.
|
||||
alignas(cache_line_size) std::atomic<index_t> w_idx {0};
|
||||
};
|
||||
|
||||
@ -125,16 +125,16 @@ struct producer<trans::unicast, relation::multi> {
|
||||
auto w_cur = trunc_index(ctx, w_idx);
|
||||
auto &elem = elems[w_cur];
|
||||
auto f_ct = elem.get_flag();
|
||||
/// @remark Verify index.
|
||||
/// \remark Verify index.
|
||||
if ((f_ct != state::invalid_value) &&
|
||||
(f_ct != w_idx)) {
|
||||
return false; // full
|
||||
}
|
||||
/// @remark Get a valid index and iterate backwards.
|
||||
/// \remark Get a valid index and iterate backwards.
|
||||
if (!ctx.w_idx.compare_exchange_weak(w_idx, w_idx + 1, std::memory_order_acq_rel)) {
|
||||
continue;
|
||||
}
|
||||
/// @remark Set data & flag.
|
||||
/// \remark Set data & flag.
|
||||
elem.set_data(std::forward<U>(src));
|
||||
elem.set_flag(static_cast<index_t>(~w_idx));
|
||||
return true;
|
||||
@ -142,12 +142,12 @@ struct producer<trans::unicast, relation::multi> {
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Single-read consumer model implementation.
|
||||
/// \brief Single-read consumer model implementation.
|
||||
template <>
|
||||
struct consumer<trans::unicast, relation::single> {
|
||||
|
||||
struct context_impl {
|
||||
/// @brief Read index.
|
||||
/// \brief Read index.
|
||||
alignas(cache_line_size) index_t r_idx {0};
|
||||
};
|
||||
|
||||
@ -159,25 +159,25 @@ struct consumer<trans::unicast, relation::single> {
|
||||
auto r_cur = trunc_index(ctx, r_idx);
|
||||
auto &elem = elems[r_cur];
|
||||
auto f_ct = elem.get_flag();
|
||||
/// @remark Verify index.
|
||||
/// \remark Verify index.
|
||||
if (f_ct != static_cast<index_t>(~r_idx)) {
|
||||
return false; // empty
|
||||
}
|
||||
/// @remark Get a valid index and iterate backwards.
|
||||
/// \remark Get a valid index and iterate backwards.
|
||||
ctx.r_idx += 1;
|
||||
/// @remark Get data & set flag.
|
||||
/// \remark Get data & set flag.
|
||||
des = elem.get_data();
|
||||
elem.set_flag(r_idx + static_cast<index_t>(elems.size()));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Multi-read consumer model implementation.
|
||||
/// \brief Multi-read consumer model implementation.
|
||||
template <>
|
||||
struct consumer<trans::unicast, relation::multi> {
|
||||
|
||||
struct context_impl {
|
||||
/// @brief Read index.
|
||||
/// \brief Read index.
|
||||
alignas(cache_line_size) std::atomic<index_t> r_idx {0};
|
||||
};
|
||||
|
||||
@ -190,15 +190,15 @@ struct consumer<trans::unicast, relation::multi> {
|
||||
auto r_cur = trunc_index(ctx, r_idx);
|
||||
auto &elem = elems[r_cur];
|
||||
auto f_ct = elem.get_flag();
|
||||
/// @remark Verify index.
|
||||
/// \remark Verify index.
|
||||
if (f_ct != static_cast<index_t>(~r_idx)) {
|
||||
return false; // empty
|
||||
}
|
||||
/// @remark Get a valid index and iterate backwards.
|
||||
/// \remark Get a valid index and iterate backwards.
|
||||
if (!ctx.r_idx.compare_exchange_weak(r_idx, r_idx + 1, std::memory_order_acq_rel)) {
|
||||
continue;
|
||||
}
|
||||
/// @remark Get data & set flag.
|
||||
/// \remark Get data & set flag.
|
||||
des = elem.get_data();
|
||||
elem.set_flag(r_idx + static_cast<index_t>(elems.size()));
|
||||
return true;
|
||||
@ -207,41 +207,41 @@ struct consumer<trans::unicast, relation::multi> {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Algorithm definition under broadcast transmission model.
|
||||
* \brief Algorithm definition under broadcast transmission model.
|
||||
*/
|
||||
|
||||
/// @brief Single-write producer model implementation.
|
||||
/// \brief Single-write producer model implementation.
|
||||
template <>
|
||||
struct producer<trans::broadcast, relation::single> {
|
||||
};
|
||||
|
||||
/// @brief Multi-write producer model implementation.
|
||||
/// \brief Multi-write producer model implementation.
|
||||
template <>
|
||||
struct producer<trans::broadcast, relation::multi> {
|
||||
};
|
||||
|
||||
/// @brief Single-read consumer model implementation.
|
||||
/// \brief Single-read consumer model implementation.
|
||||
template <>
|
||||
struct consumer<trans::broadcast, relation::single> {
|
||||
};
|
||||
|
||||
/// @brief Multi-read consumer model implementation.
|
||||
/// \brief Multi-read consumer model implementation.
|
||||
template <>
|
||||
struct consumer<trans::broadcast, relation::multi> {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Producer-consumer implementation.
|
||||
* \brief Producer-consumer implementation.
|
||||
*
|
||||
* @tparam TransModT transmission mode (trans::unicast/trans::broadcast)
|
||||
* @tparam ProdModT producer relationship model (relation::single/relation::multi)
|
||||
* @tparam ConsModT consumer relationship model (relation::single/relation::multi)
|
||||
* \tparam TransModT transmission mode (trans::unicast/trans::broadcast)
|
||||
* \tparam ProdModT producer relationship model (relation::single/relation::multi)
|
||||
* \tparam ConsModT consumer relationship model (relation::single/relation::multi)
|
||||
*/
|
||||
template <typename TransModT, typename ProdModT, typename ConsModT>
|
||||
struct prod_cons : producer<TransModT, ProdModT>
|
||||
, consumer<TransModT, ConsModT> {
|
||||
|
||||
/// @brief Mixing producer and consumer context definitions.
|
||||
/// \brief Mixing producer and consumer context definitions.
|
||||
struct context : producer<TransModT, ProdModT>::context_impl
|
||||
, consumer<TransModT, ConsModT>::context_impl {
|
||||
index_t const circ_size;
|
||||
@ -254,7 +254,7 @@ struct prod_cons : producer<TransModT, ProdModT>
|
||||
: circ_size(static_cast<index_t>(elems.size())) {}
|
||||
|
||||
constexpr bool valid() const noexcept {
|
||||
/// @remark circ_size must be a power of two.
|
||||
/// \remark circ_size must be a power of two.
|
||||
return (circ_size > 1) && ((circ_size & (circ_size - 1)) == 0);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libconcur/def.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the trivial configuration information for concurrency.
|
||||
* @date 2022-11-07
|
||||
* \file libconcur/def.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the trivial configuration information for concurrency.
|
||||
* \date 2022-11-07
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -17,11 +17,11 @@
|
||||
|
||||
LIBCONCUR_NAMESPACE_BEG_
|
||||
|
||||
/// @brief Constants.
|
||||
/// \brief Constants.
|
||||
|
||||
enum : std::size_t {
|
||||
/// @brief Minimum offset between two objects to avoid false sharing.
|
||||
/// @see https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size
|
||||
/// \brief Minimum offset between two objects to avoid false sharing.
|
||||
/// \see https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size
|
||||
cache_line_size =
|
||||
#if defined(LIBIMP_CPP_17) && defined(__cpp_lib_hardware_interference_size)
|
||||
( std::hardware_destructive_interference_size < alignof(std::max_align_t) ) ? 64
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libconcur/element.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define concurrent queue element abstraction.
|
||||
* @date 2022-11-19
|
||||
* \file libconcur/element.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define concurrent queue element abstraction.
|
||||
* \date 2022-11-19
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -20,11 +20,11 @@
|
||||
LIBCONCUR_NAMESPACE_BEG_
|
||||
namespace state {
|
||||
|
||||
/// @brief The state flag type for the queue element.
|
||||
/// \brief The state flag type for the queue element.
|
||||
using flag_t = std::uint64_t;
|
||||
|
||||
enum : flag_t {
|
||||
/// @brief The invalid state value.
|
||||
/// \brief The invalid state value.
|
||||
invalid_value = (std::numeric_limits<flag_t>::max)(),
|
||||
};
|
||||
|
||||
@ -32,12 +32,12 @@ enum : flag_t {
|
||||
|
||||
template <typename T>
|
||||
class element {
|
||||
/// @brief Committed flag.
|
||||
/// \brief Committed flag.
|
||||
alignas(cache_line_size) std::atomic<state::flag_t> f_ct_;
|
||||
/// @brief The user data segment.
|
||||
/// \brief The user data segment.
|
||||
T data_;
|
||||
|
||||
/// @brief Disable copy & move.
|
||||
/// \brief Disable copy & move.
|
||||
element(element const &) = delete;
|
||||
element &operator=(element const &) = delete;
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libconcur/queue.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define concurrent queue.
|
||||
* @date 2022-11-19
|
||||
* \file libconcur/queue.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define concurrent queue.
|
||||
* \date 2022-11-19
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/byte.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the byte type.
|
||||
* @date 2022-11-12
|
||||
* \file libimp/byte.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the byte type.
|
||||
* \date 2022-11-12
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -37,8 +37,8 @@ using is_not_byte =
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief A distinct type that implements the concept of byte as specified in the C++ language definition.
|
||||
* @see https://en.cppreference.com/w/cpp/types/byte
|
||||
* \brief A distinct type that implements the concept of byte as specified in the C++ language definition.
|
||||
* \see https://en.cppreference.com/w/cpp/types/byte
|
||||
*/
|
||||
class byte {
|
||||
std::uint8_t bits_;
|
||||
@ -63,8 +63,8 @@ public:
|
||||
|
||||
#ifdef LIBIMP_CPP_LIB_BYTE_
|
||||
explicit constexpr operator std::byte() const noexcept {
|
||||
/// @brief C++17 relaxed enum class initialization rules.
|
||||
/// @see https://en.cppreference.com/w/cpp/language/enum#enum_relaxed_init_cpp17
|
||||
/// \brief C++17 relaxed enum class initialization rules.
|
||||
/// \see https://en.cppreference.com/w/cpp/language/enum#enum_relaxed_init_cpp17
|
||||
return std::byte{bits_};
|
||||
}
|
||||
#endif // LIBIMP_CPP_LIB_BYTE_
|
||||
@ -79,7 +79,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Non-member functions.
|
||||
* \brief Non-member functions.
|
||||
*/
|
||||
|
||||
template <typename T, typename = detail::is_integral<T>>
|
||||
@ -87,7 +87,7 @@ constexpr T to_integer(byte b) noexcept {
|
||||
return T(b);
|
||||
}
|
||||
|
||||
/// @brief std::operator<<, operator>>
|
||||
/// \brief std::operator<<, operator>>
|
||||
|
||||
template <typename T, typename = detail::is_integral<T>>
|
||||
constexpr byte operator<<(byte b, T shift) noexcept {
|
||||
@ -99,7 +99,7 @@ constexpr byte operator>>(byte b, T shift) noexcept {
|
||||
return byte(to_integer<unsigned>(b) >> shift);
|
||||
}
|
||||
|
||||
/// @brief std::operator<<=, operator>>=
|
||||
/// \brief std::operator<<=, operator>>=
|
||||
|
||||
template <typename T, typename = detail::is_integral<T>>
|
||||
constexpr byte &operator<<=(byte &b, T shift) noexcept {
|
||||
@ -111,20 +111,20 @@ constexpr byte &operator>>=(byte &b, T shift) noexcept {
|
||||
return b = b >> shift;
|
||||
}
|
||||
|
||||
/// @brief std::operator|, operator&, operator^, operator~
|
||||
/// \brief std::operator|, operator&, operator^, operator~
|
||||
|
||||
constexpr byte operator|(byte l, byte r) noexcept { return byte(to_integer<unsigned>(l) | to_integer<unsigned>(r)); }
|
||||
constexpr byte operator&(byte l, byte r) noexcept { return byte(to_integer<unsigned>(l) & to_integer<unsigned>(r)); }
|
||||
constexpr byte operator^(byte l, byte r) noexcept { return byte(to_integer<unsigned>(l) ^ to_integer<unsigned>(r)); }
|
||||
constexpr byte operator~(byte b) noexcept { return byte(~to_integer<unsigned>(b)); }
|
||||
|
||||
/// @brief std::operator|=, operator&=, operator^=
|
||||
/// \brief std::operator|=, operator&=, operator^=
|
||||
|
||||
constexpr byte &operator|=(byte &l, byte r) noexcept { return l = l | r; }
|
||||
constexpr byte &operator&=(byte &l, byte r) noexcept { return l = l & r; }
|
||||
constexpr byte &operator^=(byte &l, byte r) noexcept { return l = l ^ r; }
|
||||
|
||||
/// @brief Cast pointer to byte*.
|
||||
/// \brief Cast pointer to byte*.
|
||||
|
||||
template <typename T, typename = detail::is_not_byte<T>>
|
||||
byte *byte_cast(T *p) noexcept {
|
||||
@ -136,7 +136,7 @@ byte const *byte_cast(T const *p) noexcept {
|
||||
return reinterpret_cast<byte const *>(p);
|
||||
}
|
||||
|
||||
/// @brief Cast byte* to a pointer of another type.
|
||||
/// \brief Cast byte* to a pointer of another type.
|
||||
|
||||
template <typename T, typename = detail::is_not_byte<T>>
|
||||
T *byte_cast(byte *p) noexcept {
|
||||
@ -155,8 +155,8 @@ U *byte_cast(byte const *p) noexcept {
|
||||
return reinterpret_cast<U *>(p);
|
||||
}
|
||||
|
||||
/// @brief Converts a span into a view of its underlying bytes.
|
||||
/// @see https://en.cppreference.com/w/cpp/container/span/as_bytes
|
||||
/// \brief Converts a span into a view of its underlying bytes.
|
||||
/// \see https://en.cppreference.com/w/cpp/container/span/as_bytes
|
||||
|
||||
template <typename T,
|
||||
typename Byte = typename std::conditional<std::is_const<T>::value, byte const, byte>::type>
|
||||
@ -164,7 +164,7 @@ auto as_bytes(span<T> s) noexcept -> span<Byte> {
|
||||
return {byte_cast(s.data()), s.size_bytes()};
|
||||
}
|
||||
|
||||
/// @brief Custom defined fmt_to method for imp::fmt
|
||||
/// \brief Custom defined fmt_to method for imp::fmt
|
||||
namespace detail {
|
||||
|
||||
inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, ::LIBIMP::byte b) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/codecvt.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Character set conversion interface
|
||||
* @date 2022-08-07
|
||||
* \file libimp/codecvt.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Character set conversion interface
|
||||
* \date 2022-08-07
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief The transform between UTF-8/16/32
|
||||
* \brief The transform between UTF-8/16/32
|
||||
*
|
||||
* @param des The target string pointer can be nullptr
|
||||
* @param dlen The target string length can be 0
|
||||
* \param des The target string pointer can be nullptr
|
||||
* \param dlen The target string length can be 0
|
||||
*/
|
||||
template <typename CharT, typename CharU>
|
||||
LIBIMP_EXPORT std::size_t cvt_cstr(CharT const *src, std::size_t slen, CharU *des, std::size_t dlen) noexcept;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/construct.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Construct an object from a memory buffer
|
||||
* @date 2022-02-27
|
||||
* \file libimp/construct.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Construct an object from a memory buffer
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -18,8 +18,8 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief Creates an object at a given address, like 'construct_at' in c++20
|
||||
* @see https://en.cppreference.com/w/cpp/memory/construct_at
|
||||
* \brief Creates an object at a given address, like 'construct_at' in c++20
|
||||
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
||||
*/
|
||||
|
||||
template <typename T, typename... A>
|
||||
@ -39,8 +39,8 @@ auto construct(void *p, A &&... args)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroys an object at a given address, like 'destroy_at' in c++17
|
||||
* @see https://en.cppreference.com/w/cpp/memory/destroy_at
|
||||
* \brief Destroys an object at a given address, like 'destroy_at' in c++17
|
||||
* \see https://en.cppreference.com/w/cpp/memory/destroy_at
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/countof.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Returns the size of the given range
|
||||
* @date 2022-03-01
|
||||
* \file libimp/countof.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Returns the size of the given range
|
||||
* \date 2022-03-01
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @see https://en.cppreference.com/w/cpp/iterator/size
|
||||
* \see https://en.cppreference.com/w/cpp/iterator/size
|
||||
*/
|
||||
|
||||
namespace detail_countof {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/def.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the trivial configuration information.
|
||||
* @date 2022-04-23
|
||||
* \file libimp/def.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the trivial configuration information.
|
||||
* \date 2022-04-23
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,6 +15,6 @@
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/// @brief Constants.
|
||||
/// \brief Constants.
|
||||
|
||||
LIBIMP_NAMESPACE_END_
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
/**
|
||||
* @file libimp/detect_plat.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define platform detection related interfaces.
|
||||
* @date 2022-02-27
|
||||
* \file libimp/detect_plat.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define platform detection related interfaces.
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/// @brief OS check.
|
||||
/// \brief OS check.
|
||||
|
||||
#if defined(WINCE) || defined(_WIN32_WCE)
|
||||
# define LIBIMP_OS_WINCE
|
||||
@ -35,7 +35,7 @@
|
||||
# define LIBIMP_OS_WIN
|
||||
#endif
|
||||
|
||||
/// @brief Compiler check.
|
||||
/// \brief Compiler check.
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define LIBIMP_CC_MSVC _MSC_VER
|
||||
@ -48,8 +48,8 @@
|
||||
# error "This compiler is unsupported."
|
||||
#endif
|
||||
|
||||
/// @brief Instruction set.
|
||||
/// @see https://sourceforge.net/p/predef/wiki/Architectures/
|
||||
/// \brief Instruction set.
|
||||
/// \see https://sourceforge.net/p/predef/wiki/Architectures/
|
||||
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || \
|
||||
defined(__x86_64__) || defined(__x86_64) || \
|
||||
@ -74,7 +74,7 @@
|
||||
# define LIBIMP_INSTR_ARM
|
||||
#endif
|
||||
|
||||
/// @brief Byte order.
|
||||
/// \brief Byte order.
|
||||
|
||||
#if defined(__BYTE_ORDER__)
|
||||
# define LIBIMP_ENDIAN_BIG (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
@ -84,7 +84,7 @@
|
||||
# define LIBIMP_ENDIAN_LIT (1)
|
||||
#endif
|
||||
|
||||
/// @brief C++ version.
|
||||
/// \brief C++ version.
|
||||
|
||||
#if (__cplusplus >= 202002L) && !defined(LIBIMP_CPP_20)
|
||||
# define LIBIMP_CPP_20
|
||||
@ -102,7 +102,7 @@
|
||||
# error "This C++ version is unsupported."
|
||||
#endif
|
||||
|
||||
/// @brief C++ attributes.
|
||||
/// \brief C++ attributes.
|
||||
|
||||
#if defined(__has_cpp_attribute)
|
||||
# if __has_cpp_attribute(fallthrough)
|
||||
@ -165,7 +165,7 @@
|
||||
#endif
|
||||
|
||||
#if !defined(LIBIMP_NODISCARD)
|
||||
/// @see https://stackoverflow.com/questions/4226308/msvc-equivalent-of-attribute-warn-unused-result
|
||||
/// \see https://stackoverflow.com/questions/4226308/msvc-equivalent-of-attribute-warn-unused-result
|
||||
# if defined(LIBIMP_CC_GNUC) && (LIBIMP_CC_GNUC >= 4)
|
||||
# define LIBIMP_NODISCARD __attribute__((warn_unused_result))
|
||||
# elif defined(LIBIMP_CC_MSVC) && (LIBIMP_CC_MSVC >= 1700)
|
||||
@ -175,7 +175,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/// @see https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html
|
||||
/// \see https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html
|
||||
/// https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros
|
||||
/// https://stackoverflow.com/questions/6487013/programmatically-determine-whether-exceptions-are-enabled
|
||||
#if defined(__cpp_exceptions) && __cpp_exceptions || \
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/enum_cast.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Returns the underlying type of the given enum
|
||||
* @date 2022-03-01
|
||||
* \file libimp/enum_cast.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Returns the underlying type of the given enum
|
||||
* \date 2022-03-01
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -12,6 +12,8 @@
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/// \brief Returns after converting the value to the underlying type of E.
|
||||
/// \see https://en.cppreference.com/w/cpp/types/underlying_type
|
||||
template <typename E>
|
||||
constexpr auto enum_cast(E e) noexcept {
|
||||
return static_cast<std::underlying_type_t<E>>(e);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/error.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief A platform-dependent error code.
|
||||
* @date 2022-12-18
|
||||
* \file libimp/error.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief A platform-dependent error code.
|
||||
* \date 2022-12-18
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief Serves as the base class for specific error category types.
|
||||
* @see https://en.cppreference.com/w/cpp/error/error_category
|
||||
* \brief Serves as the base class for specific error category types.
|
||||
* \see https://en.cppreference.com/w/cpp/error/error_category
|
||||
*/
|
||||
class LIBIMP_EXPORT error_category {
|
||||
public:
|
||||
@ -27,47 +27,47 @@ public:
|
||||
constexpr error_category() noexcept = default;
|
||||
virtual ~error_category() noexcept = default;
|
||||
|
||||
/// @brief observer
|
||||
/// \brief observer
|
||||
virtual std::string name() const = 0;
|
||||
virtual std::string message(result_code r) const = 0;
|
||||
|
||||
/// @brief comparison function
|
||||
/// \brief comparison function
|
||||
bool operator==(error_category const &rhs) const noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Identifies the generic error category.
|
||||
* @see https://en.cppreference.com/w/cpp/error/generic_category
|
||||
* \brief Identifies the generic error category.
|
||||
* \see https://en.cppreference.com/w/cpp/error/generic_category
|
||||
*/
|
||||
LIBIMP_EXPORT error_category const &generic_category() noexcept;
|
||||
|
||||
/**
|
||||
* @brief The error code object.
|
||||
* @see https://en.cppreference.com/w/cpp/error/error_code
|
||||
* \brief The error code object.
|
||||
* \see https://en.cppreference.com/w/cpp/error/error_code
|
||||
*/
|
||||
class LIBIMP_EXPORT error_code {
|
||||
result_code r_code_;
|
||||
error_category const *ec_;
|
||||
|
||||
public:
|
||||
/// @brief constructors
|
||||
/// \brief constructors
|
||||
error_code() noexcept;
|
||||
error_code(result_code r, error_category const &ec) noexcept;
|
||||
|
||||
/// @brief observers
|
||||
/// \brief observers
|
||||
result_code code() const noexcept;
|
||||
result_type value() const noexcept;
|
||||
error_category const &category() const noexcept;
|
||||
std::string message() const;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/// @brief comparison functions
|
||||
/// \brief comparison functions
|
||||
friend LIBIMP_EXPORT bool operator==(error_code const &lhs, error_code const &rhs) noexcept;
|
||||
friend LIBIMP_EXPORT bool operator!=(error_code const &lhs, error_code const &rhs) noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief @brief Custom defined fmt_to method for imp::fmt
|
||||
* \brief @brief Custom defined fmt_to method for imp::fmt
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/export.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the symbol export interfaces
|
||||
* @date 2022-02-27
|
||||
* \file libimp/export.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the symbol export interfaces
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,10 +15,10 @@
|
||||
|
||||
#else // defined(Q_DECL_EXPORT) && defined(Q_DECL_IMPORT)
|
||||
|
||||
/*
|
||||
* Compiler & system detection for LIBIMP_DECL_EXPORT & LIBIMP_DECL_IMPORT.
|
||||
/**
|
||||
* \brief Compiler & system detection for LIBIMP_DECL_EXPORT & LIBIMP_DECL_IMPORT.
|
||||
* Not using QtCore cause it shouldn't depend on Qt.
|
||||
*/
|
||||
*/
|
||||
# if defined(LIBIMP_CC_MSVC) || defined(LIBIMP_OS_WIN)
|
||||
# define LIBIMP_DECL_EXPORT __declspec(dllexport)
|
||||
# define LIBIMP_DECL_IMPORT __declspec(dllimport)
|
||||
@ -32,9 +32,9 @@
|
||||
|
||||
#endif // defined(Q_DECL_EXPORT) && defined(Q_DECL_IMPORT)
|
||||
|
||||
/*
|
||||
* Define LIBIMP_EXPORT for exporting function & class.
|
||||
*/
|
||||
/**
|
||||
* \brief Define LIBIMP_EXPORT for exporting function & class.
|
||||
*/
|
||||
#ifndef LIBIMP_EXPORT
|
||||
# if defined(LIBIMP_LIBRARY_SHARED_BUILDING__)
|
||||
# define LIBIMP_EXPORT LIBIMP_DECL_EXPORT
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file libimp/fmt.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief String formatting.
|
||||
* @date 2022-11-26
|
||||
* \file libimp/fmt.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief String formatting.
|
||||
* \date 2022-11-26
|
||||
*
|
||||
* @remarks The current performance is not high,
|
||||
* \remarks The current performance is not high,
|
||||
* because I use std::sprintf directly for formatting for convenience.
|
||||
*/
|
||||
#pragma once
|
||||
@ -25,7 +25,7 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief The format string reference wrapper.
|
||||
* \brief The format string reference wrapper.
|
||||
*/
|
||||
template <typename T>
|
||||
struct fmt_ref {
|
||||
@ -34,12 +34,12 @@ struct fmt_ref {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Conversion specifiers.
|
||||
* \brief Conversion specifiers.
|
||||
*
|
||||
* @remarks Just like printf, the format string is of the form
|
||||
* \remarks Just like printf, the format string is of the form
|
||||
* [flags][field_width][.precision][conversion_character]
|
||||
*
|
||||
* @see http://personal.ee.surrey.ac.uk/Personal/R.Bowden/C/printf.html
|
||||
* \see http://personal.ee.surrey.ac.uk/Personal/R.Bowden/C/printf.html
|
||||
*/
|
||||
template <std::size_t N>
|
||||
auto spec(char const (&fstr)[N]) noexcept {
|
||||
@ -50,10 +50,10 @@ auto spec(char const (&fstr)[N]) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief String formatting function.
|
||||
* \brief String formatting function.
|
||||
*
|
||||
* @param args arguments that support the fmt output
|
||||
* @return an empty string if the fmt output fails
|
||||
* \param args arguments that support the fmt output
|
||||
* \return an empty string if the fmt output fails
|
||||
*/
|
||||
template <typename... A>
|
||||
LIBIMP_NODISCARD std::string fmt(A &&...args) {
|
||||
@ -65,13 +65,13 @@ LIBIMP_NODISCARD std::string fmt(A &&...args) {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief String types.
|
||||
/// \brief String types.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char const * a) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, std::string const &a) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char const * a, span<char const> fstr) noexcept;
|
||||
inline bool to_string(fmt_context &ctx, std::string const &a, span<char const> fstr) noexcept { return to_string(ctx, a.c_str(), fstr); }
|
||||
|
||||
/// @brief Character to string conversion.
|
||||
/// \brief Character to string conversion.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char a) noexcept;
|
||||
#if defined(LIBIMP_CPP_20)
|
||||
inline bool to_string(fmt_context &ctx, char8_t a) noexcept { return to_string(ctx, (char)a); }
|
||||
@ -80,7 +80,7 @@ LIBIMP_EXPORT bool to_string(fmt_context &ctx, wchar_t a) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char16_t a) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char32_t a) noexcept;
|
||||
|
||||
/// @brief Conversion of numeric types to strings.
|
||||
/// \brief Conversion of numeric types to strings.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, signed short a, span<char const> fstr = {}) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, unsigned short a, span<char const> fstr = {}) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, signed int a, span<char const> fstr = {}) noexcept;
|
||||
@ -92,29 +92,29 @@ LIBIMP_EXPORT bool to_string(fmt_context &ctx, unsigned long long a, span<char c
|
||||
inline bool to_string(fmt_context &ctx, signed char a, span<char const> fstr = {}) noexcept { return to_string(ctx, (int)a, fstr); }
|
||||
inline bool to_string(fmt_context &ctx, unsigned char a, span<char const> fstr = {}) noexcept { return to_string(ctx, (unsigned)a, fstr); }
|
||||
|
||||
/// @brief Conversion of floating point type to strings.
|
||||
/// \brief Conversion of floating point type to strings.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, double a, span<char const> fstr = {}) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, long double a, span<char const> fstr = {}) noexcept;
|
||||
inline bool to_string(fmt_context &ctx, float a, span<char const> fstr = {}) noexcept { return to_string(ctx, (double)a, fstr); }
|
||||
|
||||
/// @brief Pointer.
|
||||
/// \brief Pointer.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, std::nullptr_t) noexcept;
|
||||
template <typename T,
|
||||
typename = std::enable_if_t<std::is_same<T, void>::value>>
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, T const volatile *a) noexcept;
|
||||
|
||||
/// @brief Date and time.
|
||||
/// \brief Date and time.
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, std::tm const &a, span<char const> fstr = {}) noexcept;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Convert std::time_t to std::string.
|
||||
* @return an empty string if the conversion fails
|
||||
* \brief Convert std::time_t to std::string.
|
||||
* \return an empty string if the conversion fails
|
||||
*/
|
||||
inline bool time_to_string(fmt_context &ctx, std::time_t tt, span<char const> fstr) noexcept {
|
||||
#if defined(LIBIMP_CC_MSVC)
|
||||
/// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-s-localtime32-s-localtime64-s
|
||||
/// \see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-s-localtime32-s-localtime64-s
|
||||
std::tm tm {};
|
||||
if (::localtime_s(&tm, &tt) != 0) {
|
||||
return {};
|
||||
@ -133,7 +133,7 @@ bool to_string(fmt_context &ctx, std::chrono::time_point<Clock, Duration> const
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Predefined fmt_to method
|
||||
* \brief Predefined fmt_to method
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/fmt_cpo.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief String formatting CPO.
|
||||
* @date 2022-11-28
|
||||
* \file libimp/fmt_cpo.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief String formatting CPO.
|
||||
* \date 2022-11-28
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief The context of fmt.
|
||||
* \brief The context of fmt.
|
||||
*/
|
||||
class LIBIMP_EXPORT fmt_context {
|
||||
std::string &joined_;
|
||||
@ -36,7 +36,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Supports custom fmt_to methods for imp::fmt.
|
||||
* \brief Supports custom fmt_to methods for imp::fmt.
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/generic.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Tools for generic programming.
|
||||
* @date 2022-03-01
|
||||
* \file libimp/generic.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Tools for generic programming.
|
||||
* \date 2022-03-01
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -14,15 +14,15 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief Utility metafunction that maps a sequence of any types to the type void
|
||||
* @see https://en.cppreference.com/w/cpp/types/void_t
|
||||
* \brief Utility metafunction that maps a sequence of any types to the type void
|
||||
* \see https://en.cppreference.com/w/cpp/types/void_t
|
||||
*/
|
||||
template <typename...>
|
||||
using void_t = void;
|
||||
|
||||
/**
|
||||
* @brief A general pattern for supporting customisable functions
|
||||
* @see https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/p1895r0.pdf
|
||||
* \brief A general pattern for supporting customisable functions
|
||||
* \see https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/p1895r0.pdf
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
@ -42,8 +42,8 @@ struct tag_invoke_t {
|
||||
constexpr detail::tag_invoke_t tag_invoke {};
|
||||
|
||||
/**
|
||||
* @brief Circumventing forwarding reference may override copy and move constructs.
|
||||
* @see https://mpark.github.io/programming/2014/06/07/beware-of-perfect-forwarding-constructors/
|
||||
* \brief Circumventing forwarding reference may override copy and move constructs.
|
||||
* \see https://mpark.github.io/programming/2014/06/07/beware-of-perfect-forwarding-constructors/
|
||||
*/
|
||||
namespace detail {
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @file libimp/horrible_cast.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @date 2022-04-17
|
||||
* \file libimp/horrible_cast.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \date 2022-04-17
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/log.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Simple log output component.
|
||||
* @date 2022-05-22
|
||||
* \file libimp/log.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Simple log output component.
|
||||
* \date 2022-05-22
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -39,7 +39,7 @@ struct context {
|
||||
LIBIMP_EXPORT std::string to_string(context &&) noexcept;
|
||||
LIBIMP_EXPORT bool to_string(fmt_context &ctx, context &&) noexcept;
|
||||
|
||||
/// @brief Custom defined fmt_to method for imp::fmt
|
||||
/// \brief Custom defined fmt_to method for imp::fmt
|
||||
template <typename T>
|
||||
bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, context &&arg) noexcept {
|
||||
return ::LIBIMP::log::to_string(ctx, std::move(arg));
|
||||
@ -121,7 +121,7 @@ public:
|
||||
printer() noexcept = default;
|
||||
|
||||
template <typename T,
|
||||
/// @remark generic constructor may shadow the default copy constructor
|
||||
/// \remark generic constructor may shadow the default copy constructor
|
||||
typename = std::enable_if_t<!std::is_same<printer, T>::value>>
|
||||
printer(T &p) noexcept
|
||||
: objp_ (static_cast<void *>(&p))
|
||||
@ -131,17 +131,17 @@ public:
|
||||
void output(context) noexcept;
|
||||
};
|
||||
|
||||
/// @brief Standard console output.
|
||||
/// \brief Standard console output.
|
||||
class LIBIMP_EXPORT std_t {
|
||||
public:
|
||||
void output(log::level, std::string &&) noexcept;
|
||||
};
|
||||
|
||||
/// @brief Standard console output object.
|
||||
/// \brief Standard console output object.
|
||||
LIBIMP_EXPORT extern std_t std_out;
|
||||
|
||||
/**
|
||||
* @brief Log information grips.
|
||||
* \brief Log information grips.
|
||||
*/
|
||||
class grip {
|
||||
printer printer_;
|
||||
@ -160,7 +160,7 @@ class grip {
|
||||
fmt(std::forward<A>(args)...),
|
||||
};
|
||||
} LIBIMP_CATCH(std::exception const &e) {
|
||||
/// @remark [TBD] std::string constructor may throw an exception
|
||||
/// \remark [TBD] std::string constructor may throw an exception
|
||||
ctx = {
|
||||
level::failed, std::chrono::system_clock::now(), func_, e.what(),
|
||||
};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/nameof.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Gets the name string of a type.
|
||||
* @date 2022-11-26
|
||||
* \file libimp/nameof.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Gets the name string of a type.
|
||||
* \date 2022-11-26
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -16,20 +16,20 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @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
|
||||
* \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
|
||||
* \param name the mangled name
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
std::string demangle(span<char const> 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
|
||||
* \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
|
||||
* \tparam T a type
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
template <typename T>
|
||||
std::string nameof() noexcept {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/pimpl.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Pointer To Implementation (pImpl) idiom
|
||||
* @date 2022-02-27
|
||||
* \file libimp/pimpl.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Pointer To Implementation (pImpl) idiom
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
/**
|
||||
* @file libimp/result.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the return value type with a status code
|
||||
* @date 2022-04-17
|
||||
* \file libimp/result.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the return value type with a status code
|
||||
* \date 2022-04-17
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <cstdint>
|
||||
|
||||
#include "libimp/def.h"
|
||||
@ -18,10 +19,10 @@
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
using result_type = std::uint64_t;
|
||||
using result_type = std::tuple<std::uint64_t, bool>;
|
||||
|
||||
/**
|
||||
* @brief Use the least significant (in Little-Endian) of
|
||||
* \brief Use the least significant (in Little-Endian) of
|
||||
* a 64-bit unsigned integer to indicate success or failure,
|
||||
* so the data significant bit cannot exceed 63 bits.
|
||||
*/
|
||||
@ -62,7 +63,7 @@ namespace detail_result {
|
||||
|
||||
template <typename T>
|
||||
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
/// @brief Custom initialization.
|
||||
/// \brief Custom initialization.
|
||||
constexpr static void init_code(result_code &code) noexcept {
|
||||
code = {};
|
||||
}
|
||||
@ -73,17 +74,17 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
init_code(code, true, value);
|
||||
}
|
||||
|
||||
/// @brief Custom default value.
|
||||
/// \brief Custom default value.
|
||||
constexpr static T default_value() noexcept {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @brief Custom type conversions.
|
||||
/// \brief Custom type conversions.
|
||||
constexpr static T cast_from_code(result_code code) noexcept {
|
||||
return static_cast<T>(code.value());
|
||||
}
|
||||
|
||||
/// @brief Custom formatted output.
|
||||
/// \brief Custom formatted output.
|
||||
static std::string format(result<T> const &r) noexcept {
|
||||
return fmt(*r);
|
||||
}
|
||||
@ -91,7 +92,7 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
|
||||
|
||||
template <typename T>
|
||||
struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> {
|
||||
/// @brief Custom initialization.
|
||||
/// \brief Custom initialization.
|
||||
constexpr static void init_code(result_code &code, T value = default_value()) noexcept {
|
||||
code = {default_value() != value, reinterpret_cast<result_type>(value)};
|
||||
}
|
||||
@ -102,17 +103,17 @@ struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> {
|
||||
code = {false, r};
|
||||
}
|
||||
|
||||
/// @brief Custom default value.
|
||||
/// \brief Custom default value.
|
||||
constexpr static T default_value() noexcept {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief Custom type conversions.
|
||||
/// \brief Custom type conversions.
|
||||
constexpr static T cast_from_code(result_code code) noexcept {
|
||||
return code.ok() ? reinterpret_cast<T>(code.value()) : default_value();
|
||||
}
|
||||
|
||||
/// @brief Custom formatted output.
|
||||
/// \brief Custom formatted output.
|
||||
static std::string format(result<T> const &r) noexcept {
|
||||
if LIBIMP_LIKELY(r) {
|
||||
return fmt(static_cast<void *>(*r));
|
||||
@ -126,7 +127,7 @@ struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> {
|
||||
template <typename T, typename TypeTraits>
|
||||
class result : public TypeTraits {
|
||||
|
||||
/// @brief Internal data is stored using result_code.
|
||||
/// \brief Internal data is stored using result_code.
|
||||
result_code code_;
|
||||
|
||||
public:
|
||||
@ -156,7 +157,7 @@ public:
|
||||
friend bool operator!=(result const &lhs, result const &rhs) noexcept { return lhs.code_ != rhs.code_; }
|
||||
};
|
||||
|
||||
/// @brief Custom defined fmt_to method for imp::fmt
|
||||
/// \brief Custom defined fmt_to method for imp::fmt
|
||||
namespace detail {
|
||||
|
||||
inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, result_code r) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/span.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Describes an object that can refer to a contiguous sequence of objects
|
||||
* @date 2022-10-16
|
||||
* \file libimp/span.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Describes an object that can refer to a contiguous sequence of objects
|
||||
* \date 2022-10-16
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
namespace detail {
|
||||
|
||||
/// @brief Helper trait for span.
|
||||
/// \brief Helper trait for span.
|
||||
|
||||
template <typename From, typename To>
|
||||
using array_convertible = std::is_convertible<From(*)[], To(*)[]>;
|
||||
@ -56,9 +56,9 @@ using is_sized_sentinel_for =
|
||||
typename std::enable_if<std::is_convertible<decltype(std::declval<S>() - std::declval<I>()),
|
||||
std::ptrdiff_t>::value>::type;
|
||||
|
||||
/// @brief Obtain the address represented by p
|
||||
/// \brief Obtain the address represented by p
|
||||
/// without forming a reference to the object pointed to by p.
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/to_address
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/to_address
|
||||
|
||||
template<typename T>
|
||||
constexpr T *to_address(T *ptr) noexcept {
|
||||
@ -76,8 +76,8 @@ constexpr auto to_address(T const &ptr)
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief A simple implementation of span.
|
||||
* @see https://en.cppreference.com/w/cpp/container/span
|
||||
* \brief A simple implementation of span.
|
||||
* \see https://en.cppreference.com/w/cpp/container/span
|
||||
*/
|
||||
template <typename T>
|
||||
class span {
|
||||
@ -205,7 +205,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Support for span equals comparison.
|
||||
/// \brief Support for span equals comparison.
|
||||
|
||||
template <typename T, typename U,
|
||||
typename = decltype(std::declval<T>() == std::declval<U>())>
|
||||
@ -219,9 +219,9 @@ bool operator==(span<T> a, span<U> b) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Constructs an object of type T and wraps it in a span.
|
||||
/// \brief Constructs an object of type T and wraps it in a span.
|
||||
/// Before C++17, template argument deduction for class templates was not supported.
|
||||
/// @see https://en.cppreference.com/w/cpp/language/template_argument_deduction
|
||||
/// \see https://en.cppreference.com/w/cpp/language/template_argument_deduction
|
||||
|
||||
template <typename T>
|
||||
auto make_span(T *arr, std::size_t count) noexcept -> span<T> {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libimp/system.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Isolation and encapsulation of system APIs
|
||||
* @date 2022-08-07
|
||||
* \file libimp/system.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Isolation and encapsulation of system APIs
|
||||
* \date 2022-08-07
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -18,30 +18,30 @@ LIBIMP_NAMESPACE_BEG_
|
||||
namespace sys {
|
||||
|
||||
/**
|
||||
* @brief Get/Set the system error number
|
||||
* \brief Get/Set the system error number
|
||||
*/
|
||||
LIBIMP_EXPORT result_code error_no() noexcept;
|
||||
LIBIMP_EXPORT void error_no(result_code) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Gets a text description of the system error
|
||||
* \brief Gets a text description of the system error
|
||||
*/
|
||||
LIBIMP_EXPORT std::string error_str(result_code) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Identifies the operating system error category.
|
||||
* @see https://en.cppreference.com/w/cpp/error/system_category
|
||||
* \brief Identifies the operating system error category.
|
||||
* \see https://en.cppreference.com/w/cpp/error/system_category
|
||||
*/
|
||||
LIBIMP_EXPORT error_category const &category() noexcept;
|
||||
|
||||
/**
|
||||
* @brief A platform-dependent error code.
|
||||
* @see https://en.cppreference.com/w/cpp/error/error_code
|
||||
* \brief A platform-dependent error code.
|
||||
* \see https://en.cppreference.com/w/cpp/error/error_code
|
||||
*/
|
||||
LIBIMP_EXPORT error_code error() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Get system configuration information at run time
|
||||
* \brief Get system configuration information at run time
|
||||
*/
|
||||
enum class info : std::int32_t {
|
||||
page_size,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libipc/def.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the trivial configuration information.
|
||||
* @date 2022-02-27
|
||||
* \file libipc/def.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the trivial configuration information.
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
/// @brief Constants.
|
||||
/// \brief Constants.
|
||||
|
||||
struct prot {
|
||||
using type = std::uint32_t;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libipc/shm.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the shared memory access interface
|
||||
* @date 2022-04-17
|
||||
* \file libipc/shm.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the shared memory access interface
|
||||
* \date 2022-04-17
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -19,32 +19,32 @@ LIBIPC_NAMESPACE_BEG_
|
||||
struct shm_handle;
|
||||
using shm_t = shm_handle *;
|
||||
|
||||
/// @brief Create a new shared memory handle with a name of the shared memory file.
|
||||
/// \brief Create a new shared memory handle with a name of the shared memory file.
|
||||
LIBIMP_EXPORT ::LIBIMP::result<shm_t> shm_open(std::string name,
|
||||
std::size_t size = 0,
|
||||
mode::type = mode::create | mode::open) noexcept;
|
||||
|
||||
/// @brief Close the shared memory handle.
|
||||
/// \brief Close the shared memory handle.
|
||||
LIBIMP_EXPORT ::LIBIMP::result_code shm_close(shm_t) noexcept;
|
||||
|
||||
/// @brief Gets a memory pointer based on the shared memory handle.
|
||||
/// @return nullptr on failure.
|
||||
/// \brief Gets a memory pointer based on the shared memory handle.
|
||||
/// \return nullptr on failure.
|
||||
LIBIMP_EXPORT void *shm_get(shm_t) noexcept;
|
||||
|
||||
/// @brief Gets the memory size based on the shared memory handle.
|
||||
/// @return 0 on failure.
|
||||
/// \brief Gets the memory size based on the shared memory handle.
|
||||
/// \return 0 on failure.
|
||||
LIBIMP_EXPORT std::size_t shm_size(shm_t) noexcept;
|
||||
|
||||
/// @brief Sets the memory size based on the shared memory handle.
|
||||
/// @remark [TBD]
|
||||
/// \brief Sets the memory size based on the shared memory handle.
|
||||
/// \remark [TBD]
|
||||
LIBIMP_EXPORT ::LIBIMP::result_code shm_size(shm_t, std::size_t) noexcept;
|
||||
|
||||
/// @brief Gets the name of the shared memory file based on the shared memory handle.
|
||||
/// @return empty string on failure.
|
||||
/// \brief Gets the name of the shared memory file based on the shared memory handle.
|
||||
/// \return empty string on failure.
|
||||
LIBIMP_EXPORT std::string shm_name(shm_t) noexcept;
|
||||
|
||||
/**
|
||||
* @brief The shared memory object.
|
||||
* \brief The shared memory object.
|
||||
*/
|
||||
class LIBIMP_EXPORT shared_memory {
|
||||
shm_t shm_;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libipc/spin_lock.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define spin locks
|
||||
* @date 2022-02-27
|
||||
* \file libipc/spin_lock.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define spin locks
|
||||
* \date 2022-02-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -18,12 +18,12 @@
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief Gives hint to processor that improves performance of spin-wait loops.
|
||||
* \brief Gives hint to processor that improves performance of spin-wait loops.
|
||||
*/
|
||||
LIBIMP_EXPORT void pause() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Yield to other threads
|
||||
* \brief Yield to other threads
|
||||
*/
|
||||
|
||||
template <typename K>
|
||||
@ -60,7 +60,7 @@ inline void sleep(K &k) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Basic spin lock
|
||||
* \brief Basic spin lock
|
||||
*/
|
||||
class LIBIMP_EXPORT spin_lock {
|
||||
std::atomic<unsigned> lc_ {0};
|
||||
@ -71,7 +71,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Support for shared mode spin lock
|
||||
* \brief Support for shared mode spin lock
|
||||
*/
|
||||
class LIBIMP_EXPORT rw_lock {
|
||||
std::atomic<unsigned> lc_ {0};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libpmr/allocator.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief A generic polymorphic memory allocator.
|
||||
* @date 2022-11-13
|
||||
* \file libpmr/allocator.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief A generic polymorphic memory allocator.
|
||||
* \date 2022-11-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -19,15 +19,15 @@
|
||||
LIBPMR_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief An allocator which exhibits different allocation behavior
|
||||
* \brief An allocator which exhibits different allocation behavior
|
||||
* depending upon the memory resource from which it is constructed.
|
||||
*
|
||||
* @remarks Unlike std::pmr::polymorphic_allocator, it does not
|
||||
* \remarks Unlike std::pmr::polymorphic_allocator, it does not
|
||||
* rely on a specific inheritance relationship and only restricts
|
||||
* the interface behavior of the incoming memory resource object to
|
||||
* conform to std::pmr::memory_resource.
|
||||
*
|
||||
* @see https://en.cppreference.com/w/cpp/memory/memory_resource
|
||||
* \see https://en.cppreference.com/w/cpp/memory/memory_resource
|
||||
* https://en.cppreference.com/w/cpp/memory/polymorphic_allocator
|
||||
*/
|
||||
class LIBIMP_EXPORT allocator {
|
||||
@ -51,8 +51,8 @@ class LIBIMP_EXPORT allocator {
|
||||
class holder_memory_resource;
|
||||
|
||||
/**
|
||||
* @brief A memory resource pointer holder class for type erasure.
|
||||
* @tparam MR memory resource type
|
||||
* \brief A memory resource pointer holder class for type erasure.
|
||||
* \tparam MR memory resource type
|
||||
*/
|
||||
template <typename MR>
|
||||
class holder_memory_resource<MR, is_memory_resource<MR>> : public holder_base {
|
||||
@ -76,8 +76,8 @@ class LIBIMP_EXPORT allocator {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief An empty holding class used to calculate a reasonable memory size for the holder.
|
||||
* @tparam MR cannot be converted to the type of memory resource
|
||||
* \brief An empty holding class used to calculate a reasonable memory size for the holder.
|
||||
* \tparam MR cannot be converted to the type of memory resource
|
||||
*/
|
||||
template <typename MR, typename U>
|
||||
class holder_memory_resource : public holder_null {
|
||||
@ -100,8 +100,8 @@ public:
|
||||
allocator(allocator &&other) noexcept;
|
||||
allocator &operator=(allocator &&other) & noexcept;
|
||||
|
||||
/// @brief Constructs a allocator from a memory resource pointer
|
||||
/// @remark The lifetime of the pointer must be longer than that of allocator.
|
||||
/// \brief Constructs a allocator from a memory resource pointer
|
||||
/// The lifetime of the pointer must be longer than that of allocator.
|
||||
template <typename T, typename = is_memory_resource<T>>
|
||||
allocator(T *p_mr) : allocator() {
|
||||
if (p_mr == nullptr) return;
|
||||
@ -112,7 +112,7 @@ public:
|
||||
bool valid() const noexcept;
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/// @brief Allocate/deallocate memory.
|
||||
/// \brief Allocate/deallocate memory.
|
||||
void *alloc(std::size_t s);
|
||||
void free (void *p, std::size_t s);
|
||||
};
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libpmr/def.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Define the trivial configuration information for memory resources.
|
||||
* @date 2022-11-13
|
||||
* \file libpmr/def.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Define the trivial configuration information for memory resources.
|
||||
* \date 2022-11-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -12,6 +12,6 @@
|
||||
|
||||
LIBPMR_NAMESPACE_BEG_
|
||||
|
||||
/// @brief Constants.
|
||||
/// \brief Constants.
|
||||
|
||||
LIBPMR_NAMESPACE_END_
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @file libpmr/memory_resource.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* @brief Implement memory allocation strategies that can be used by pmr::allocator.
|
||||
* @date 2022-11-13
|
||||
* \file libpmr/memory_resource.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Implement memory allocation strategies that can be used by pmr::allocator.
|
||||
* \date 2022-11-13
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
|
||||
LIBPMR_NAMESPACE_BEG_
|
||||
|
||||
/// @brief Helper trait for memory resource.
|
||||
/// \brief Helper trait for memory resource.
|
||||
|
||||
template <typename T, typename = void>
|
||||
struct has_allocate : std::false_type {};
|
||||
@ -40,23 +40,23 @@ using is_memory_resource =
|
||||
has_deallocate<T>::value>::type;
|
||||
|
||||
/**
|
||||
* @brief A memory resource that uses the
|
||||
* \brief A memory resource that uses the
|
||||
* standard memory allocation and deallocation interface to allocate memory.
|
||||
*
|
||||
* @see https://en.cppreference.com/w/cpp/memory/new_delete_resource
|
||||
* \see https://en.cppreference.com/w/cpp/memory/new_delete_resource
|
||||
*/
|
||||
class LIBIMP_EXPORT new_delete_resource {
|
||||
public:
|
||||
/// @brief Returns a pointer to a new_delete_resource.
|
||||
/// \brief Returns a pointer to a new_delete_resource.
|
||||
static new_delete_resource *get() noexcept;
|
||||
|
||||
/// @brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
|
||||
/// @remark Returns nullptr if storage of the requested size and alignment cannot be obtained.
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate
|
||||
/// \brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
|
||||
/// \remark Returns nullptr if storage of the requested size and alignment cannot be obtained.
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate
|
||||
void *allocate(std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
|
||||
|
||||
/// @brief Deallocates the storage pointed to by p.
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/memory_resource/deallocate
|
||||
/// \brief Deallocates the storage pointed to by p.
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/memory_resource/deallocate
|
||||
void deallocate(void *p, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
|
||||
};
|
||||
|
||||
|
||||
@ -15,19 +15,19 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief The transform between local-character-set(UTF-8/GBK/...) and UTF-16/32.
|
||||
* \brief The transform between local-character-set(UTF-8/GBK/...) and UTF-16/32.
|
||||
*
|
||||
* Modified from UnicodeConverter.
|
||||
* Copyright (c) 2010. Jianhui Qin (http://blog.csdn.net/jhqin).
|
||||
*
|
||||
* @remarks codecvt_utf8_utf16/std::wstring_convert is deprecated.
|
||||
* @see https://codingtidbit.com/2020/02/09/c17-codecvt_utf8-is-deprecated/
|
||||
* \remarks codecvt_utf8_utf16/std::wstring_convert is deprecated.
|
||||
* \see https://codingtidbit.com/2020/02/09/c17-codecvt_utf8-is-deprecated/
|
||||
* https://stackoverflow.com/questions/42946335/deprecated-header-codecvt-replacement
|
||||
* https://en.cppreference.com/w/cpp/locale/codecvt/in
|
||||
*/
|
||||
namespace {
|
||||
|
||||
/// @brief X-bit unicode transformation format
|
||||
/// \brief X-bit unicode transformation format
|
||||
enum class ufmt {
|
||||
utf8,
|
||||
utf16,
|
||||
@ -53,7 +53,7 @@ template <typename T, ufmt Fmt>
|
||||
constexpr bool utf_compatible_v = utf_compatible<T, Fmt>::value;
|
||||
|
||||
/**
|
||||
* @brief UTF-32 --> UTF-8
|
||||
* \brief UTF-32 --> UTF-8
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T src, U* des, std::size_t dlen) noexcept
|
||||
@ -91,7 +91,7 @@ auto cvt_char(T src, U* des, std::size_t dlen) noexcept
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-8 --> UTF-32
|
||||
* \brief UTF-8 --> UTF-32
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T const *src, std::size_t slen, U &des) noexcept
|
||||
@ -138,7 +138,7 @@ auto cvt_char(T const *src, std::size_t slen, U &des) noexcept
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-32 --> UTF-16
|
||||
* \brief UTF-32 --> UTF-16
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T src, U *des, std::size_t dlen) noexcept
|
||||
@ -162,7 +162,7 @@ auto cvt_char(T src, U *des, std::size_t dlen) noexcept
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-16 --> UTF-32
|
||||
* \brief UTF-16 --> UTF-32
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T const *src, std::size_t slen, U &des)
|
||||
@ -188,7 +188,7 @@ auto cvt_char(T const *src, std::size_t slen, U &des)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-16 --> UTF-8
|
||||
* \brief UTF-16 --> UTF-8
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T src, U *des, std::size_t dlen) noexcept
|
||||
@ -202,7 +202,7 @@ auto cvt_char(T src, U *des, std::size_t dlen) noexcept
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-8 --> UTF-16
|
||||
* \brief UTF-8 --> UTF-16
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_char(T const *src, std::size_t slen, U &des)
|
||||
@ -218,7 +218,7 @@ auto cvt_char(T const *src, std::size_t slen, U &des)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-32 string --> UTF-8/16 string
|
||||
* \brief UTF-32 string --> UTF-8/16 string
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept
|
||||
@ -247,7 +247,7 @@ auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noex
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-8/16 string --> UTF-32 string
|
||||
* \brief UTF-8/16 string --> UTF-32 string
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept
|
||||
@ -276,7 +276,7 @@ auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noex
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UTF-8/16 string --> UTF-16/8 string
|
||||
* \brief UTF-8/16 string --> UTF-16/8 string
|
||||
*/
|
||||
template <typename T, typename U>
|
||||
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @brief Format conversions helpers.
|
||||
* @see http://personal.ee.surrey.ac.uk/Personal/R.Bowden/C/printf.html
|
||||
* \brief Format conversions helpers.
|
||||
* \see http://personal.ee.surrey.ac.uk/Personal/R.Bowden/C/printf.html
|
||||
* https://en.cppreference.com/w/cpp/io/c/fprintf
|
||||
*/
|
||||
namespace {
|
||||
@ -149,7 +149,7 @@ span<char> fmt_context_sbuf() noexcept {
|
||||
|
||||
} // namespace
|
||||
|
||||
/// @brief The context of fmt.
|
||||
/// \brief The context of fmt.
|
||||
|
||||
fmt_context::fmt_context(std::string &j) noexcept
|
||||
: joined_(j)
|
||||
@ -189,7 +189,7 @@ span<char> fmt_context::buffer(std::size_t sz) noexcept {
|
||||
if ((offset_ + sz) < sbuf.size()) {
|
||||
return sbuf.subspan(offset_);
|
||||
} else {
|
||||
/// @remark switch the cache to std::string
|
||||
/// \remark switch the cache to std::string
|
||||
joined_.assign(sbuf.data(), offset_);
|
||||
joined_.resize(roundup(offset_ + sz));
|
||||
}
|
||||
@ -216,7 +216,7 @@ bool fmt_context::append(std::string const &str) noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief To string conversion.
|
||||
/// \brief To string conversion.
|
||||
|
||||
bool to_string(fmt_context &ctx, char const *a) noexcept {
|
||||
return to_string(ctx, a, {});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libimp/platform/gnuc/demangle.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libimp/platform/gnuc/demangle.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,15 +15,15 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @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
|
||||
* \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
|
||||
* \param name the mangled name
|
||||
* \return std::string a human-readable demangled type name
|
||||
*/
|
||||
std::string demangle(span<char const> name) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
/// @see https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
|
||||
/// \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;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libimp/platform/posix/system.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libimp/platform/posix/system.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -19,7 +19,7 @@ namespace sys {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the system error number
|
||||
* \brief Get the system error number
|
||||
* https://man7.org/linux/man-pages/man3/errno.3.html
|
||||
*/
|
||||
result_code error_no() noexcept {
|
||||
@ -29,7 +29,7 @@ result_code error_no() noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the system error number
|
||||
* \brief Set the system error number
|
||||
* https://man7.org/linux/man-pages/man3/errno.3.html
|
||||
*/
|
||||
void error_no(result_code code) noexcept {
|
||||
@ -37,7 +37,7 @@ void error_no(result_code code) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a text description of the system error
|
||||
* \brief Gets a text description of the system error
|
||||
* https://man7.org/linux/man-pages/man3/strerror_l.3.html
|
||||
* https://manpages.ubuntu.com/manpages/xenial/en/man3/strerror.3.html
|
||||
*/
|
||||
@ -58,7 +58,7 @@ std::string error_str(result_code code) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets configuration information at run time
|
||||
* \brief Gets configuration information at run time
|
||||
* https://man7.org/linux/man-pages/man2/getpagesize.2.html
|
||||
* https://man7.org/linux/man-pages/man3/sysconf.3.html
|
||||
*/
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libimp/platform/win/codecvt.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libimp/platform/win/codecvt.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
|
||||
*
|
||||
* CP_ACP : The system default Windows ANSI code page.
|
||||
@ -57,7 +57,7 @@ std::size_t cvt_cstr(wchar_t const *src, std::size_t slen, char *des, std::size_
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Used for char8_t (since C++20) to wchar_t conversion.
|
||||
* \brief Used for char8_t (since C++20) to wchar_t conversion.
|
||||
*
|
||||
* There is no ut to guarantee correctness (I'm a little lazy here),
|
||||
* so if there are any bugs, please contact me in time.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libimp/platform/win/demangle.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libimp/platform/win/demangle.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libimp/platform/win/system.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libimp/platform/win/system.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -21,7 +21,7 @@ LIBIMP_NAMESPACE_BEG_
|
||||
namespace sys {
|
||||
|
||||
/**
|
||||
* @brief Get the system error number
|
||||
* \brief Get the system error number
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
|
||||
*/
|
||||
result_code error_no() noexcept {
|
||||
@ -33,7 +33,7 @@ result_code error_no() noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the system error number
|
||||
* \brief Set the system error number
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror
|
||||
*/
|
||||
void error_no(result_code code) noexcept {
|
||||
@ -42,7 +42,7 @@ void error_no(result_code code) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets a text description of the system error
|
||||
* \brief Gets a text description of the system error
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage
|
||||
*/
|
||||
std::string error_str(result_code code) noexcept {
|
||||
@ -81,7 +81,7 @@ std::string error_str(result_code code) noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves information about the current system
|
||||
* \brief Retrieves information about the current system
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsysteminfo
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
|
||||
*/
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/posix/mmap.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/posix/mmap.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/posix/shm_impl.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/posix/shm_impl.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -54,7 +54,7 @@ result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief Open the object for read-write access.
|
||||
/// \brief Open the object for read-write access.
|
||||
int flag = O_RDWR;
|
||||
switch (type) {
|
||||
case mode::open:
|
||||
@ -73,7 +73,7 @@ result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief Create/Open POSIX shared memory bject
|
||||
/// \brief Create/Open POSIX shared memory bject
|
||||
return ::shm_open(name.c_str(), flag, S_IRUSR | S_IWUSR |
|
||||
S_IRGRP | S_IWGRP |
|
||||
S_IROTH | S_IWOTH);
|
||||
@ -81,7 +81,7 @@ result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
|
||||
|
||||
result_code ftruncate_fd(int fd, std::size_t size) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
/// @see https://man7.org/linux/man-pages/man3/ftruncate.3p.html
|
||||
/// \see https://man7.org/linux/man-pages/man3/ftruncate.3p.html
|
||||
if (::ftruncate(fd, size) != posix::succ) {
|
||||
auto err = sys::error();
|
||||
log.error("failed: ftruncate(", fd, ", ", size, "). error = ", err);
|
||||
@ -93,7 +93,7 @@ result_code ftruncate_fd(int fd, std::size_t size) noexcept {
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @see https://man7.org/linux/man-pages/man3/shm_open.3.html
|
||||
* \see https://man7.org/linux/man-pages/man3/shm_open.3.html
|
||||
* https://man7.org/linux/man-pages/man3/fstat.3p.html
|
||||
* https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||
*/
|
||||
@ -112,25 +112,25 @@ result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noex
|
||||
if (pfd != nullptr) ::close(**pfd);
|
||||
}};
|
||||
|
||||
/// @brief Try to get the size of this fd
|
||||
/// \brief Try to get the size of this fd
|
||||
struct stat st;
|
||||
if (::fstat(*fd, &st) == posix::failed) {
|
||||
log.error("failed: fstat(fd = ", *fd, "). error = ", sys::error());
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief Truncate this fd to a specified length
|
||||
/// \brief Truncate this fd to a specified length
|
||||
if (size == 0) {
|
||||
size = static_cast<std::size_t>(st.st_size);
|
||||
if (!ftruncate_fd(*fd, size)) return {};
|
||||
} else if (st.st_size > 0) {
|
||||
/// @remark Based on the actual size.
|
||||
/// \remark Based on the actual size.
|
||||
size = static_cast<std::size_t>(st.st_size);
|
||||
} else { // st.st_size <= 0
|
||||
if (!ftruncate_fd(*fd, size)) return {};
|
||||
}
|
||||
|
||||
/// @brief Creates a new mapping in the virtual address space of the calling process.
|
||||
/// \brief Creates a new mapping in the virtual address space of the calling process.
|
||||
void *mem = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
|
||||
if (mem == MAP_FAILED) {
|
||||
log.error("failed: mmap(size = ", size, ", fd = ", *fd, "). error = ", sys::error());
|
||||
@ -140,7 +140,7 @@ result<shm_t> shm_open(std::string name, std::size_t size, mode::type type) noex
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||
* \see https://man7.org/linux/man-pages/man2/mmap.2.html
|
||||
*/
|
||||
result_code shm_close(shm_t h) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
@ -151,7 +151,7 @@ result_code shm_close(shm_t h) noexcept {
|
||||
log.error("failed: munmap(", shm->memp, ", ", shm->f_sz, "). error = ", err);
|
||||
return err.code();
|
||||
}
|
||||
/// @brief no unlink the file.
|
||||
/// \brief no unlink the file.
|
||||
delete shm;
|
||||
return {posix::succ};
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/win/get_sa.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/win/get_sa.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -15,8 +15,8 @@ LIBIPC_NAMESPACE_BEG_
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Create a SECURITY_ATTRIBUTES structure singleton
|
||||
* @see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
|
||||
* \brief Create a SECURITY_ATTRIBUTES structure singleton
|
||||
* \see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
|
||||
*/
|
||||
inline LPSECURITY_ATTRIBUTES get_sa() {
|
||||
static struct initiator {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/win/mmap_impl.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/win/mmap_impl.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
@ -30,8 +30,8 @@ struct shm_handle {
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* @brief Closes an open object handle.
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
|
||||
* \brief Closes an open object handle.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
|
||||
*/
|
||||
result_code mmap_close(HANDLE h) {
|
||||
LIBIMP_LOG_();
|
||||
@ -48,17 +48,17 @@ result_code mmap_close(HANDLE h) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates or opens a file mapping object for a specified file.
|
||||
* \brief Creates or opens a file mapping object for a specified file.
|
||||
*
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilemappinga
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilemappinga
|
||||
* https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga
|
||||
*
|
||||
* @param file Specifies the name of the file mapping object
|
||||
* @param size Specifies the size required to create a file mapping object.
|
||||
* \param file Specifies the name of the file mapping object
|
||||
* \param size Specifies the size required to create a file mapping object.
|
||||
* This size is ignored when opening an existing file mapping object
|
||||
* @param type Combinable open modes, create | open
|
||||
* \param type Combinable open modes, create | open
|
||||
*
|
||||
* @return File mapping object HANDLE, NULL on error
|
||||
* \return File mapping object HANDLE, NULL on error
|
||||
*/
|
||||
result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
@ -72,7 +72,7 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief Opens a named file mapping object.
|
||||
/// \brief Opens a named file mapping object.
|
||||
auto try_open = [&]() -> result<HANDLE> {
|
||||
HANDLE h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, t_name.c_str());
|
||||
if (h == NULL) {
|
||||
@ -83,10 +83,10 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
return h;
|
||||
};
|
||||
|
||||
/// @brief Creates or opens a named or unnamed file mapping object for a specified file.
|
||||
/// \brief Creates or opens a named or unnamed file mapping object for a specified file.
|
||||
auto try_create = [&]() -> result<HANDLE> {
|
||||
HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT,
|
||||
/// @remark dwMaximumSizeHigh always 0 here.
|
||||
/// \remark dwMaximumSizeHigh always 0 here.
|
||||
0, static_cast<DWORD>(size), t_name.c_str());
|
||||
if (h == NULL) {
|
||||
auto err = sys::error();
|
||||
@ -99,8 +99,8 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
if (type == mode::open) {
|
||||
return try_open();
|
||||
} else if ((type == (mode::create | mode::open)) && (size == 0)) {
|
||||
/// @remark CreateFileMapping may returns ERROR_INVALID_PARAMETER when dwMaximumSizeLow is zero.
|
||||
/// @see CreateFileMapping (Windows CE 5.0)
|
||||
/// \remark CreateFileMapping may returns ERROR_INVALID_PARAMETER when dwMaximumSizeLow is zero.
|
||||
/// \see CreateFileMapping (Windows CE 5.0)
|
||||
/// https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa517331(v=msdn.10)
|
||||
return try_open();
|
||||
} else if (!(type & mode::create)) {
|
||||
@ -109,7 +109,7 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
}
|
||||
auto h = try_create();
|
||||
if (!h) return h;
|
||||
/// @remark If the object exists before the function call, the function returns a handle to the existing object
|
||||
/// \remark If the object exists before the function call, the function returns a handle to the existing object
|
||||
/// (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
|
||||
if ((type == mode::create) && (::GetLastError() == ERROR_ALREADY_EXISTS)) {
|
||||
log.info("the file being created already exists. file = ", file, ", type = ", type);
|
||||
@ -120,8 +120,8 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Maps a view of a file mapping into the address space of a calling process.
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
|
||||
* \brief Maps a view of a file mapping into the address space of a calling process.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
|
||||
*/
|
||||
result<LPVOID> mmap_memof(HANDLE h) {
|
||||
LIBIMP_LOG_();
|
||||
@ -139,8 +139,8 @@ result<LPVOID> mmap_memof(HANDLE h) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the size about a range of pages in the virtual address space of the calling process.
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
|
||||
* \brief Retrieves the size about a range of pages in the virtual address space of the calling process.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
|
||||
*/
|
||||
result<SIZE_T> mmap_sizeof(LPCVOID mem) {
|
||||
LIBIMP_LOG_();
|
||||
@ -158,8 +158,8 @@ result<SIZE_T> mmap_sizeof(LPCVOID mem) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unmaps a mapped view of a file from the calling process's address space.
|
||||
* @see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
|
||||
* \brief Unmaps a mapped view of a file from the calling process's address space.
|
||||
* \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
|
||||
*/
|
||||
result_code mmap_release(HANDLE h, LPCVOID mem) {
|
||||
LIBIMP_LOG_();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/win/shm_impl.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/win/shm_impl.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file libipc/platform/win/to_tchar.h
|
||||
* @author mutouyun (orz@orzz.org)
|
||||
* \file libipc/platform/win/to_tchar.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
/// @brief C style shared memory access interface implementation.
|
||||
/// \brief C style shared memory access interface implementation.
|
||||
|
||||
void *shm_get(shm_t h) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
@ -44,7 +44,7 @@ std::string shm_name(shm_t h) noexcept {
|
||||
return shm->file;
|
||||
}
|
||||
|
||||
/// @brief The shared memory object.
|
||||
/// \brief The shared memory object.
|
||||
|
||||
shared_memory::shared_memory() noexcept
|
||||
: shm_(nullptr) {}
|
||||
|
||||
@ -10,29 +10,29 @@ LIBIPC_NAMESPACE_BEG_
|
||||
#if defined(LIBIMP_CC_MSVC)
|
||||
# include <Windows.h> // YieldProcessor
|
||||
/**
|
||||
* @brief Not for intel c++ compiler, so ignore http://software.intel.com/en-us/forums/topic/296168
|
||||
* @see http://msdn.microsoft.com/en-us/library/windows/desktop/ms687419(v=vs.85).aspx
|
||||
* \brief Not for intel c++ compiler, so ignore http://software.intel.com/en-us/forums/topic/296168
|
||||
* \see http://msdn.microsoft.com/en-us/library/windows/desktop/ms687419(v=vs.85).aspx
|
||||
*/
|
||||
# define LIBIPC_LOCK_PAUSE_() YieldProcessor()
|
||||
#elif defined(LIBIMP_CC_GNUC)
|
||||
# if defined(LIBIMP_INSTR_X86_64)
|
||||
/**
|
||||
* @brief Intel(R) 64 and IA-32 Architectures Software Developer's Manual V2
|
||||
* \brief Intel(R) 64 and IA-32 Architectures Software Developer's Manual V2
|
||||
* PAUSE-Spin Loop Hint, 4-57
|
||||
* @see http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.html?wapkw=instruction+set+reference
|
||||
* \see http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.html?wapkw=instruction+set+reference
|
||||
*/
|
||||
# define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__("pause")
|
||||
# elif defined(LIBIMP_INSTR_I64)
|
||||
/**
|
||||
* @brief Intel(R) Itanium(R) Architecture Developer's Manual, Vol.3
|
||||
* \brief Intel(R) Itanium(R) Architecture Developer's Manual, Vol.3
|
||||
* hint - Performance Hint, 3:145
|
||||
* @see http://www.intel.com/content/www/us/en/processors/itanium/itanium-architecture-vol-3-manual.html
|
||||
* \see http://www.intel.com/content/www/us/en/processors/itanium/itanium-architecture-vol-3-manual.html
|
||||
*/
|
||||
# define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__ ("hint @pause")
|
||||
# elif defined(LIBIMP_INSTR_ARM)
|
||||
/**
|
||||
* @brief ARM Architecture Reference Manuals (YIELD)
|
||||
* @see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html
|
||||
* \brief ARM Architecture Reference Manuals (YIELD)
|
||||
* \see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html
|
||||
*/
|
||||
# define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__ ("yield")
|
||||
# endif
|
||||
@ -40,20 +40,20 @@ LIBIPC_NAMESPACE_BEG_
|
||||
|
||||
#if !defined(LIBIPC_LOCK_PAUSE_)
|
||||
/**
|
||||
* @brief Just use a compiler fence, prevent compiler from optimizing loop
|
||||
* \brief Just use a compiler fence, prevent compiler from optimizing loop
|
||||
*/
|
||||
# define LIBIPC_LOCK_PAUSE_() std::atomic_signal_fence(std::memory_order_seq_cst)
|
||||
#endif /*!defined(LIBIPC_LOCK_PAUSE_)*/
|
||||
|
||||
/**
|
||||
* @brief Gives hint to processor that improves performance of spin-wait loops.
|
||||
* \brief Gives hint to processor that improves performance of spin-wait loops.
|
||||
*/
|
||||
void pause() noexcept {
|
||||
LIBIPC_LOCK_PAUSE_();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Basic spin lock
|
||||
* \brief Basic spin lock
|
||||
*/
|
||||
|
||||
void spin_lock::lock() noexcept {
|
||||
@ -66,14 +66,14 @@ void spin_lock::unlock() noexcept {
|
||||
lc_.store(0, std::memory_order_release);
|
||||
}
|
||||
|
||||
/// @brief Constants for shared mode spin lock
|
||||
/// \brief Constants for shared mode spin lock
|
||||
enum : unsigned {
|
||||
w_mask = (std::numeric_limits<std::make_signed_t<unsigned>>::max)(), // b 0111 1111
|
||||
w_flag = w_mask + 1, // b 1000 0000
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Support for shared mode spin lock
|
||||
* \brief Support for shared mode spin lock
|
||||
*/
|
||||
|
||||
void rw_lock::lock() noexcept {
|
||||
|
||||
@ -11,7 +11,7 @@ LIBPMR_NAMESPACE_BEG_
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* @brief Check that bytes is not 0 and that the alignment is a power of two.
|
||||
* \brief Check that bytes is not 0 and that the alignment is a power of two.
|
||||
*/
|
||||
bool verify_args(::LIBIMP::log::grip &log, std::size_t bytes, std::size_t alignment) noexcept {
|
||||
if (bytes == 0) {
|
||||
@ -27,9 +27,9 @@ bool verify_args(::LIBIMP::log::grip &log, std::size_t bytes, std::size_t alignm
|
||||
} // namespace
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to a new_delete_resource.
|
||||
* \brief Returns a pointer to a new_delete_resource.
|
||||
*
|
||||
* @return new_delete_resource*
|
||||
* \return new_delete_resource*
|
||||
*/
|
||||
new_delete_resource *new_delete_resource::get() noexcept {
|
||||
static new_delete_resource mem_res;
|
||||
@ -37,13 +37,13 @@ new_delete_resource *new_delete_resource::get() noexcept {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
|
||||
* @remark Alignment shall be a power of two.
|
||||
* \brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
|
||||
* Alignment shall be a power of two.
|
||||
*
|
||||
* @see https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate
|
||||
* \see https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate
|
||||
* https://www.cppstories.com/2019/08/newnew-align/
|
||||
*
|
||||
* @return void * - nullptr if storage of the requested size and alignment cannot be obtained.
|
||||
* \return void * - nullptr if storage of the requested size and alignment cannot be obtained.
|
||||
*/
|
||||
void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
@ -51,18 +51,18 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
|
||||
return nullptr;
|
||||
}
|
||||
#if defined(LIBIMP_CPP_17)
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/c/aligned_alloc
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/c/aligned_alloc
|
||||
return std::aligned_alloc(alignment, bytes);
|
||||
#else
|
||||
if (alignment <= alignof(std::max_align_t)) {
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/c/malloc
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/c/malloc
|
||||
return std::malloc(bytes);
|
||||
}
|
||||
#if defined(LIBIMP_OS_WIN)
|
||||
/// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc
|
||||
/// \see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-malloc
|
||||
return ::_aligned_malloc(bytes, alignment);
|
||||
#else // try posix
|
||||
/// @see https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
|
||||
/// \see https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html
|
||||
void *p = nullptr;
|
||||
int ret = ::posix_memalign(&p, alignment, bytes);
|
||||
if (ret != 0) {
|
||||
@ -77,12 +77,12 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deallocates the storage pointed to by p.
|
||||
* @remark The storage it points to must not yet have been deallocated, otherwise the behavior is undefined.
|
||||
* \brief Deallocates the storage pointed to by p.
|
||||
* The storage it points to must not yet have been deallocated, otherwise the behavior is undefined.
|
||||
*
|
||||
* @see https://en.cppreference.com/w/cpp/memory/memory_resource/do_deallocate
|
||||
* \see https://en.cppreference.com/w/cpp/memory/memory_resource/do_deallocate
|
||||
*
|
||||
* @param p must have been returned by a prior call to new_delete_resource::do_allocate(bytes, alignment).
|
||||
* \param p must have been returned by a prior call to new_delete_resource::do_allocate(bytes, alignment).
|
||||
*/
|
||||
void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept {
|
||||
LIBIMP_LOG_();
|
||||
@ -93,7 +93,7 @@ void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t ali
|
||||
return;
|
||||
}
|
||||
#if defined(LIBIMP_CPP_17)
|
||||
/// @see https://en.cppreference.com/w/cpp/memory/c/free
|
||||
/// \see https://en.cppreference.com/w/cpp/memory/c/free
|
||||
std::free(p);
|
||||
#else
|
||||
if (alignment <= alignof(std::max_align_t)) {
|
||||
@ -101,7 +101,7 @@ void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t ali
|
||||
return;
|
||||
}
|
||||
#if defined(LIBIMP_OS_WIN)
|
||||
/// @see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-free
|
||||
/// \see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/aligned-free
|
||||
::_aligned_free(p);
|
||||
#else // try posix
|
||||
::free(p);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@ -75,8 +76,10 @@ TEST(result, fmt) {
|
||||
EXPECT_EQ(imp::fmt(r0), imp::fmt(imp::result_code()));
|
||||
imp::result<int> r1 {false, -123};
|
||||
EXPECT_EQ(imp::fmt(r1), imp::fmt("[fail, value = ", -123, "]"));
|
||||
|
||||
imp::result<void *> r2 {&r1};
|
||||
EXPECT_EQ(imp::fmt(r2), imp::fmt("[succ, value = ", (void *)&r1, "]"));
|
||||
|
||||
int aaa {};
|
||||
imp::result<int *> r3 {&aaa};
|
||||
EXPECT_EQ(imp::fmt(r3), imp::fmt("[succ, value = ", (void *)&aaa, "]"));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user