upd: comment style

This commit is contained in:
mutouyun 2022-12-24 19:26:06 +08:00
parent 3880639699
commit 424bb73c94
46 changed files with 447 additions and 441 deletions

View File

@ -1,8 +1,8 @@
/** /**
* @file libconcur/concurrent.h * \file libconcur/concurrent.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define different policies for concurrent queue. * \brief Define different policies for concurrent queue.
* @date 2022-11-07 * \date 2022-11-07
*/ */
#pragma once #pragma once
@ -17,10 +17,10 @@
LIBCONCUR_NAMESPACE_BEG_ LIBCONCUR_NAMESPACE_BEG_
/// @brief The queue index type. /// \brief The queue index type.
using index_t = std::uint32_t; using index_t = std::uint32_t;
/// @brief Multiplicity of the relationship. /// \brief Multiplicity of the relationship.
namespace relation { namespace relation {
class single {}; class single {};
@ -28,7 +28,7 @@ class multi {};
} // namespace relation } // namespace relation
/// @brief Transmission mode /// \brief Transmission mode
namespace trans { namespace trans {
class unicast {}; class unicast {};
@ -36,52 +36,52 @@ class broadcast {};
} // namespace trans } // 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> template <typename T, typename U>
using is_convertible = typename std::enable_if<std::is_convertible<T *, U *>::value>::type; 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> template <typename T>
using is_context = decltype(typename std::enable_if<std::is_convertible<decltype( using is_context = decltype(typename std::enable_if<std::is_convertible<decltype(
std::declval<T>().valid()), bool>::value>::type(), std::declval<T>().valid()), bool>::value>::type(),
std::declval<index_t>() % std::declval<T>().circ_size); 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 * \tparam C a context type
* @param ctx a context object * \param ctx a context object
* @param idx a context array index * \param idx a context array index
* @return index_t - a corresponding queue position * \return index_t - a corresponding queue position
*/ */
template <typename C, typename = is_context<C>> template <typename C, typename = is_context<C>>
constexpr index_t trunc_index(C const &ctx, index_t idx) noexcept { 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; return ctx.valid() ? (idx % ctx.circ_size) : 0;
} }
/// @brief Producer algorithm implementation. /// \brief Producer algorithm implementation.
template <typename TransModT, typename RelationT> template <typename TransModT, typename RelationT>
struct producer; struct producer;
/// @brief Consumer algorithm implementation. /// \brief Consumer algorithm implementation.
template <typename TransModT, typename RelationT> template <typename TransModT, typename RelationT>
struct consumer; 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. * Modified from MengRao/WFMPMC.
* Copyright (c) 2018. Meng Rao (https://github.com/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 <> template <>
struct producer<trans::unicast, relation::single> { struct producer<trans::unicast, relation::single> {
struct context_impl { struct context_impl {
/// @brief Write index. /// \brief Write index.
alignas(cache_line_size) index_t w_idx {0}; 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 w_cur = trunc_index(ctx, w_idx);
auto &elem = elems[w_cur]; auto &elem = elems[w_cur];
auto f_ct = elem.get_flag(); auto f_ct = elem.get_flag();
/// @remark Verify index. /// \remark Verify index.
if ((f_ct != state::invalid_value) && if ((f_ct != state::invalid_value) &&
(f_ct != w_idx)) { (f_ct != w_idx)) {
return false; // full return false; // full
} }
/// @remark Get a valid index and iterate backwards. /// \remark Get a valid index and iterate backwards.
ctx.w_idx += 1; ctx.w_idx += 1;
/// @remark Set data & flag. /// \remark Set data & flag.
elem.set_data(std::forward<U>(src)); elem.set_data(std::forward<U>(src));
elem.set_flag(static_cast<index_t>(~w_idx)); elem.set_flag(static_cast<index_t>(~w_idx));
return true; return true;
} }
}; };
/// @brief Multi-write producer model implementation. /// \brief Multi-write producer model implementation.
template <> template <>
struct producer<trans::unicast, relation::multi> { struct producer<trans::unicast, relation::multi> {
struct context_impl { struct context_impl {
/// @brief Write index. /// \brief Write index.
alignas(cache_line_size) std::atomic<index_t> w_idx {0}; 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 w_cur = trunc_index(ctx, w_idx);
auto &elem = elems[w_cur]; auto &elem = elems[w_cur];
auto f_ct = elem.get_flag(); auto f_ct = elem.get_flag();
/// @remark Verify index. /// \remark Verify index.
if ((f_ct != state::invalid_value) && if ((f_ct != state::invalid_value) &&
(f_ct != w_idx)) { (f_ct != w_idx)) {
return false; // full 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)) { if (!ctx.w_idx.compare_exchange_weak(w_idx, w_idx + 1, std::memory_order_acq_rel)) {
continue; continue;
} }
/// @remark Set data & flag. /// \remark Set data & flag.
elem.set_data(std::forward<U>(src)); elem.set_data(std::forward<U>(src));
elem.set_flag(static_cast<index_t>(~w_idx)); elem.set_flag(static_cast<index_t>(~w_idx));
return true; 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 <> template <>
struct consumer<trans::unicast, relation::single> { struct consumer<trans::unicast, relation::single> {
struct context_impl { struct context_impl {
/// @brief Read index. /// \brief Read index.
alignas(cache_line_size) index_t r_idx {0}; 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 r_cur = trunc_index(ctx, r_idx);
auto &elem = elems[r_cur]; auto &elem = elems[r_cur];
auto f_ct = elem.get_flag(); auto f_ct = elem.get_flag();
/// @remark Verify index. /// \remark Verify index.
if (f_ct != static_cast<index_t>(~r_idx)) { if (f_ct != static_cast<index_t>(~r_idx)) {
return false; // empty return false; // empty
} }
/// @remark Get a valid index and iterate backwards. /// \remark Get a valid index and iterate backwards.
ctx.r_idx += 1; ctx.r_idx += 1;
/// @remark Get data & set flag. /// \remark Get data & set flag.
des = elem.get_data(); des = elem.get_data();
elem.set_flag(r_idx + static_cast<index_t>(elems.size())); elem.set_flag(r_idx + static_cast<index_t>(elems.size()));
return true; return true;
} }
}; };
/// @brief Multi-read consumer model implementation. /// \brief Multi-read consumer model implementation.
template <> template <>
struct consumer<trans::unicast, relation::multi> { struct consumer<trans::unicast, relation::multi> {
struct context_impl { struct context_impl {
/// @brief Read index. /// \brief Read index.
alignas(cache_line_size) std::atomic<index_t> r_idx {0}; 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 r_cur = trunc_index(ctx, r_idx);
auto &elem = elems[r_cur]; auto &elem = elems[r_cur];
auto f_ct = elem.get_flag(); auto f_ct = elem.get_flag();
/// @remark Verify index. /// \remark Verify index.
if (f_ct != static_cast<index_t>(~r_idx)) { if (f_ct != static_cast<index_t>(~r_idx)) {
return false; // empty 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)) { if (!ctx.r_idx.compare_exchange_weak(r_idx, r_idx + 1, std::memory_order_acq_rel)) {
continue; continue;
} }
/// @remark Get data & set flag. /// \remark Get data & set flag.
des = elem.get_data(); des = elem.get_data();
elem.set_flag(r_idx + static_cast<index_t>(elems.size())); elem.set_flag(r_idx + static_cast<index_t>(elems.size()));
return true; 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 <> template <>
struct producer<trans::broadcast, relation::single> { struct producer<trans::broadcast, relation::single> {
}; };
/// @brief Multi-write producer model implementation. /// \brief Multi-write producer model implementation.
template <> template <>
struct producer<trans::broadcast, relation::multi> { struct producer<trans::broadcast, relation::multi> {
}; };
/// @brief Single-read consumer model implementation. /// \brief Single-read consumer model implementation.
template <> template <>
struct consumer<trans::broadcast, relation::single> { struct consumer<trans::broadcast, relation::single> {
}; };
/// @brief Multi-read consumer model implementation. /// \brief Multi-read consumer model implementation.
template <> template <>
struct consumer<trans::broadcast, relation::multi> { struct consumer<trans::broadcast, relation::multi> {
}; };
/** /**
* @brief Producer-consumer implementation. * \brief Producer-consumer implementation.
* *
* @tparam TransModT transmission mode (trans::unicast/trans::broadcast) * \tparam TransModT transmission mode (trans::unicast/trans::broadcast)
* @tparam ProdModT producer relationship model (relation::single/relation::multi) * \tparam ProdModT producer relationship model (relation::single/relation::multi)
* @tparam ConsModT consumer relationship model (relation::single/relation::multi) * \tparam ConsModT consumer relationship model (relation::single/relation::multi)
*/ */
template <typename TransModT, typename ProdModT, typename ConsModT> template <typename TransModT, typename ProdModT, typename ConsModT>
struct prod_cons : producer<TransModT, ProdModT> struct prod_cons : producer<TransModT, ProdModT>
, consumer<TransModT, ConsModT> { , consumer<TransModT, ConsModT> {
/// @brief Mixing producer and consumer context definitions. /// \brief Mixing producer and consumer context definitions.
struct context : producer<TransModT, ProdModT>::context_impl struct context : producer<TransModT, ProdModT>::context_impl
, consumer<TransModT, ConsModT>::context_impl { , consumer<TransModT, ConsModT>::context_impl {
index_t const circ_size; index_t const circ_size;
@ -254,7 +254,7 @@ struct prod_cons : producer<TransModT, ProdModT>
: circ_size(static_cast<index_t>(elems.size())) {} : circ_size(static_cast<index_t>(elems.size())) {}
constexpr bool valid() const noexcept { 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); return (circ_size > 1) && ((circ_size & (circ_size - 1)) == 0);
} }
}; };

View File

@ -1,8 +1,8 @@
/** /**
* @file libconcur/def.h * \file libconcur/def.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the trivial configuration information for concurrency. * \brief Define the trivial configuration information for concurrency.
* @date 2022-11-07 * \date 2022-11-07
*/ */
#pragma once #pragma once
@ -17,11 +17,11 @@
LIBCONCUR_NAMESPACE_BEG_ LIBCONCUR_NAMESPACE_BEG_
/// @brief Constants. /// \brief Constants.
enum : std::size_t { enum : std::size_t {
/// @brief Minimum offset between two objects to avoid false sharing. /// \brief Minimum offset between two objects to avoid false sharing.
/// @see https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size /// \see https://en.cppreference.com/w/cpp/thread/hardware_destructive_interference_size
cache_line_size = cache_line_size =
#if defined(LIBIMP_CPP_17) && defined(__cpp_lib_hardware_interference_size) #if defined(LIBIMP_CPP_17) && defined(__cpp_lib_hardware_interference_size)
( std::hardware_destructive_interference_size < alignof(std::max_align_t) ) ? 64 ( std::hardware_destructive_interference_size < alignof(std::max_align_t) ) ? 64

View File

@ -1,8 +1,8 @@
/** /**
* @file libconcur/element.h * \file libconcur/element.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define concurrent queue element abstraction. * \brief Define concurrent queue element abstraction.
* @date 2022-11-19 * \date 2022-11-19
*/ */
#pragma once #pragma once
@ -20,11 +20,11 @@
LIBCONCUR_NAMESPACE_BEG_ LIBCONCUR_NAMESPACE_BEG_
namespace state { 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; using flag_t = std::uint64_t;
enum : flag_t { enum : flag_t {
/// @brief The invalid state value. /// \brief The invalid state value.
invalid_value = (std::numeric_limits<flag_t>::max)(), invalid_value = (std::numeric_limits<flag_t>::max)(),
}; };
@ -32,12 +32,12 @@ enum : flag_t {
template <typename T> template <typename T>
class element { class element {
/// @brief Committed flag. /// \brief Committed flag.
alignas(cache_line_size) std::atomic<state::flag_t> f_ct_; alignas(cache_line_size) std::atomic<state::flag_t> f_ct_;
/// @brief The user data segment. /// \brief The user data segment.
T data_; T data_;
/// @brief Disable copy & move. /// \brief Disable copy & move.
element(element const &) = delete; element(element const &) = delete;
element &operator=(element const &) = delete; element &operator=(element const &) = delete;

View File

@ -1,8 +1,8 @@
/** /**
* @file libconcur/queue.h * \file libconcur/queue.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define concurrent queue. * \brief Define concurrent queue.
* @date 2022-11-19 * \date 2022-11-19
*/ */
#pragma once #pragma once

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/byte.h * \file libimp/byte.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the byte type. * \brief Define the byte type.
* @date 2022-11-12 * \date 2022-11-12
*/ */
#pragma once #pragma once
@ -37,8 +37,8 @@ using is_not_byte =
} // namespace detail } // namespace detail
/** /**
* @brief A distinct type that implements the concept of byte as specified in the C++ language definition. * \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 * \see https://en.cppreference.com/w/cpp/types/byte
*/ */
class byte { class byte {
std::uint8_t bits_; std::uint8_t bits_;
@ -63,8 +63,8 @@ public:
#ifdef LIBIMP_CPP_LIB_BYTE_ #ifdef LIBIMP_CPP_LIB_BYTE_
explicit constexpr operator std::byte() const noexcept { explicit constexpr operator std::byte() const noexcept {
/// @brief C++17 relaxed enum class initialization rules. /// \brief C++17 relaxed enum class initialization rules.
/// @see https://en.cppreference.com/w/cpp/language/enum#enum_relaxed_init_cpp17 /// \see https://en.cppreference.com/w/cpp/language/enum#enum_relaxed_init_cpp17
return std::byte{bits_}; return std::byte{bits_};
} }
#endif // LIBIMP_CPP_LIB_BYTE_ #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>> template <typename T, typename = detail::is_integral<T>>
@ -87,7 +87,7 @@ constexpr T to_integer(byte b) noexcept {
return T(b); return T(b);
} }
/// @brief std::operator<<, operator>> /// \brief std::operator<<, operator>>
template <typename T, typename = detail::is_integral<T>> template <typename T, typename = detail::is_integral<T>>
constexpr byte operator<<(byte b, T shift) noexcept { 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); return byte(to_integer<unsigned>(b) >> shift);
} }
/// @brief std::operator<<=, operator>>= /// \brief std::operator<<=, operator>>=
template <typename T, typename = detail::is_integral<T>> template <typename T, typename = detail::is_integral<T>>
constexpr byte &operator<<=(byte &b, T shift) noexcept { constexpr byte &operator<<=(byte &b, T shift) noexcept {
@ -111,20 +111,20 @@ constexpr byte &operator>>=(byte &b, T shift) noexcept {
return b = b >> shift; 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 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)); } 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; } 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>> template <typename T, typename = detail::is_not_byte<T>>
byte *byte_cast(T *p) noexcept { byte *byte_cast(T *p) noexcept {
@ -136,7 +136,7 @@ byte const *byte_cast(T const *p) noexcept {
return reinterpret_cast<byte const *>(p); 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>> template <typename T, typename = detail::is_not_byte<T>>
T *byte_cast(byte *p) noexcept { T *byte_cast(byte *p) noexcept {
@ -155,8 +155,8 @@ U *byte_cast(byte const *p) noexcept {
return reinterpret_cast<U *>(p); return reinterpret_cast<U *>(p);
} }
/// @brief Converts a span into a view of its underlying bytes. /// \brief Converts a span into a view of its underlying bytes.
/// @see https://en.cppreference.com/w/cpp/container/span/as_bytes /// \see https://en.cppreference.com/w/cpp/container/span/as_bytes
template <typename T, template <typename T,
typename Byte = typename std::conditional<std::is_const<T>::value, byte const, byte>::type> 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()}; 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 { namespace detail {
inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, ::LIBIMP::byte b) { inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, ::LIBIMP::byte b) {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/codecvt.h * \file libimp/codecvt.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Character set conversion interface * \brief Character set conversion interface
* @date 2022-08-07 * \date 2022-08-07
*/ */
#pragma once #pragma once
@ -15,10 +15,10 @@
LIBIMP_NAMESPACE_BEG_ 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 des The target string pointer can be nullptr
* @param dlen The target string length can be 0 * \param dlen The target string length can be 0
*/ */
template <typename CharT, typename CharU> 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; LIBIMP_EXPORT std::size_t cvt_cstr(CharT const *src, std::size_t slen, CharU *des, std::size_t dlen) noexcept;

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/construct.h * \file libimp/construct.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Construct an object from a memory buffer * \brief Construct an object from a memory buffer
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once
@ -18,8 +18,8 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief Creates an object at a given address, like 'construct_at' in c++20 * \brief Creates an object at a given address, like 'construct_at' in c++20
* @see https://en.cppreference.com/w/cpp/memory/construct_at * \see https://en.cppreference.com/w/cpp/memory/construct_at
*/ */
template <typename T, typename... A> 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 * \brief Destroys an object at a given address, like 'destroy_at' in c++17
* @see https://en.cppreference.com/w/cpp/memory/destroy_at * \see https://en.cppreference.com/w/cpp/memory/destroy_at
*/ */
template <typename T> template <typename T>

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/countof.h * \file libimp/countof.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Returns the size of the given range * \brief Returns the size of the given range
* @date 2022-03-01 * \date 2022-03-01
*/ */
#pragma once #pragma once
@ -15,7 +15,7 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @see https://en.cppreference.com/w/cpp/iterator/size * \see https://en.cppreference.com/w/cpp/iterator/size
*/ */
namespace detail_countof { namespace detail_countof {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/def.h * \file libimp/def.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the trivial configuration information. * \brief Define the trivial configuration information.
* @date 2022-04-23 * \date 2022-04-23
*/ */
#pragma once #pragma once
@ -15,6 +15,6 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/// @brief Constants. /// \brief Constants.
LIBIMP_NAMESPACE_END_ LIBIMP_NAMESPACE_END_

View File

@ -1,12 +1,12 @@
/** /**
* @file libimp/detect_plat.h * \file libimp/detect_plat.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define platform detection related interfaces. * \brief Define platform detection related interfaces.
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once
/// @brief OS check. /// \brief OS check.
#if defined(WINCE) || defined(_WIN32_WCE) #if defined(WINCE) || defined(_WIN32_WCE)
# define LIBIMP_OS_WINCE # define LIBIMP_OS_WINCE
@ -35,7 +35,7 @@
# define LIBIMP_OS_WIN # define LIBIMP_OS_WIN
#endif #endif
/// @brief Compiler check. /// \brief Compiler check.
#if defined(_MSC_VER) #if defined(_MSC_VER)
# define LIBIMP_CC_MSVC _MSC_VER # define LIBIMP_CC_MSVC _MSC_VER
@ -48,8 +48,8 @@
# error "This compiler is unsupported." # error "This compiler is unsupported."
#endif #endif
/// @brief Instruction set. /// \brief Instruction set.
/// @see https://sourceforge.net/p/predef/wiki/Architectures/ /// \see https://sourceforge.net/p/predef/wiki/Architectures/
#if defined(_M_X64) || defined(_M_AMD64) || \ #if defined(_M_X64) || defined(_M_AMD64) || \
defined(__x86_64__) || defined(__x86_64) || \ defined(__x86_64__) || defined(__x86_64) || \
@ -74,7 +74,7 @@
# define LIBIMP_INSTR_ARM # define LIBIMP_INSTR_ARM
#endif #endif
/// @brief Byte order. /// \brief Byte order.
#if defined(__BYTE_ORDER__) #if defined(__BYTE_ORDER__)
# define LIBIMP_ENDIAN_BIG (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) # define LIBIMP_ENDIAN_BIG (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
@ -84,7 +84,7 @@
# define LIBIMP_ENDIAN_LIT (1) # define LIBIMP_ENDIAN_LIT (1)
#endif #endif
/// @brief C++ version. /// \brief C++ version.
#if (__cplusplus >= 202002L) && !defined(LIBIMP_CPP_20) #if (__cplusplus >= 202002L) && !defined(LIBIMP_CPP_20)
# define LIBIMP_CPP_20 # define LIBIMP_CPP_20
@ -102,7 +102,7 @@
# error "This C++ version is unsupported." # error "This C++ version is unsupported."
#endif #endif
/// @brief C++ attributes. /// \brief C++ attributes.
#if defined(__has_cpp_attribute) #if defined(__has_cpp_attribute)
# if __has_cpp_attribute(fallthrough) # if __has_cpp_attribute(fallthrough)
@ -165,7 +165,7 @@
#endif #endif
#if !defined(LIBIMP_NODISCARD) #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) # if defined(LIBIMP_CC_GNUC) && (LIBIMP_CC_GNUC >= 4)
# define LIBIMP_NODISCARD __attribute__((warn_unused_result)) # define LIBIMP_NODISCARD __attribute__((warn_unused_result))
# elif defined(LIBIMP_CC_MSVC) && (LIBIMP_CC_MSVC >= 1700) # elif defined(LIBIMP_CC_MSVC) && (LIBIMP_CC_MSVC >= 1700)
@ -175,7 +175,7 @@
# endif # endif
#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://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros
/// https://stackoverflow.com/questions/6487013/programmatically-determine-whether-exceptions-are-enabled /// https://stackoverflow.com/questions/6487013/programmatically-determine-whether-exceptions-are-enabled
#if defined(__cpp_exceptions) && __cpp_exceptions || \ #if defined(__cpp_exceptions) && __cpp_exceptions || \

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/enum_cast.h * \file libimp/enum_cast.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Returns the underlying type of the given enum * \brief Returns the underlying type of the given enum
* @date 2022-03-01 * \date 2022-03-01
*/ */
#pragma once #pragma once
@ -12,6 +12,8 @@
LIBIMP_NAMESPACE_BEG_ 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> template <typename E>
constexpr auto enum_cast(E e) noexcept { constexpr auto enum_cast(E e) noexcept {
return static_cast<std::underlying_type_t<E>>(e); return static_cast<std::underlying_type_t<E>>(e);

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/error.h * \file libimp/error.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief A platform-dependent error code. * \brief A platform-dependent error code.
* @date 2022-12-18 * \date 2022-12-18
*/ */
#pragma once #pragma once
@ -16,8 +16,8 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief Serves as the base class for specific error category types. * \brief Serves as the base class for specific error category types.
* @see https://en.cppreference.com/w/cpp/error/error_category * \see https://en.cppreference.com/w/cpp/error/error_category
*/ */
class LIBIMP_EXPORT error_category { class LIBIMP_EXPORT error_category {
public: public:
@ -27,47 +27,47 @@ public:
constexpr error_category() noexcept = default; constexpr error_category() noexcept = default;
virtual ~error_category() noexcept = default; virtual ~error_category() noexcept = default;
/// @brief observer /// \brief observer
virtual std::string name() const = 0; virtual std::string name() const = 0;
virtual std::string message(result_code r) 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; bool operator==(error_category const &rhs) const noexcept;
}; };
/** /**
* @brief Identifies the generic error category. * \brief Identifies the generic error category.
* @see https://en.cppreference.com/w/cpp/error/generic_category * \see https://en.cppreference.com/w/cpp/error/generic_category
*/ */
LIBIMP_EXPORT error_category const &generic_category() noexcept; LIBIMP_EXPORT error_category const &generic_category() noexcept;
/** /**
* @brief The error code object. * \brief The error code object.
* @see https://en.cppreference.com/w/cpp/error/error_code * \see https://en.cppreference.com/w/cpp/error/error_code
*/ */
class LIBIMP_EXPORT error_code { class LIBIMP_EXPORT error_code {
result_code r_code_; result_code r_code_;
error_category const *ec_; error_category const *ec_;
public: public:
/// @brief constructors /// \brief constructors
error_code() noexcept; error_code() noexcept;
error_code(result_code r, error_category const &ec) noexcept; error_code(result_code r, error_category const &ec) noexcept;
/// @brief observers /// \brief observers
result_code code() const noexcept; result_code code() const noexcept;
result_type value() const noexcept; result_type value() const noexcept;
error_category const &category() const noexcept; error_category const &category() const noexcept;
std::string message() const; std::string message() const;
explicit operator bool() const noexcept; 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;
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 { namespace detail {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/export.h * \file libimp/export.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the symbol export interfaces * \brief Define the symbol export interfaces
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once
@ -15,10 +15,10 @@
#else // defined(Q_DECL_EXPORT) && defined(Q_DECL_IMPORT) #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. * Not using QtCore cause it shouldn't depend on Qt.
*/ */
# if defined(LIBIMP_CC_MSVC) || defined(LIBIMP_OS_WIN) # if defined(LIBIMP_CC_MSVC) || defined(LIBIMP_OS_WIN)
# define LIBIMP_DECL_EXPORT __declspec(dllexport) # define LIBIMP_DECL_EXPORT __declspec(dllexport)
# define LIBIMP_DECL_IMPORT __declspec(dllimport) # define LIBIMP_DECL_IMPORT __declspec(dllimport)
@ -32,9 +32,9 @@
#endif // defined(Q_DECL_EXPORT) && defined(Q_DECL_IMPORT) #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 #ifndef LIBIMP_EXPORT
# if defined(LIBIMP_LIBRARY_SHARED_BUILDING__) # if defined(LIBIMP_LIBRARY_SHARED_BUILDING__)
# define LIBIMP_EXPORT LIBIMP_DECL_EXPORT # define LIBIMP_EXPORT LIBIMP_DECL_EXPORT

View File

@ -1,10 +1,10 @@
/** /**
* @file libimp/fmt.h * \file libimp/fmt.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief String formatting. * \brief String formatting.
* @date 2022-11-26 * \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. * because I use std::sprintf directly for formatting for convenience.
*/ */
#pragma once #pragma once
@ -25,7 +25,7 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief The format string reference wrapper. * \brief The format string reference wrapper.
*/ */
template <typename T> template <typename T>
struct fmt_ref { 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] * [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> template <std::size_t N>
auto spec(char const (&fstr)[N]) noexcept { 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 * \param args arguments that support the fmt output
* @return an empty string if the fmt output fails * \return an empty string if the fmt output fails
*/ */
template <typename... A> template <typename... A>
LIBIMP_NODISCARD std::string fmt(A &&...args) { LIBIMP_NODISCARD std::string fmt(A &&...args) {
@ -65,13 +65,13 @@ LIBIMP_NODISCARD std::string fmt(A &&...args) {
return {}; 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, 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, std::string const &a) noexcept;
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char const * a, span<char const> fstr) 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); } 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; LIBIMP_EXPORT bool to_string(fmt_context &ctx, char a) noexcept;
#if defined(LIBIMP_CPP_20) #if defined(LIBIMP_CPP_20)
inline bool to_string(fmt_context &ctx, char8_t a) noexcept { return to_string(ctx, (char)a); } 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, char16_t a) noexcept;
LIBIMP_EXPORT bool to_string(fmt_context &ctx, char32_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, 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, unsigned short a, span<char const> fstr = {}) noexcept;
LIBIMP_EXPORT bool to_string(fmt_context &ctx, signed int 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, 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); } 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, double a, span<char const> fstr = {}) noexcept;
LIBIMP_EXPORT bool to_string(fmt_context &ctx, long 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); } 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; LIBIMP_EXPORT bool to_string(fmt_context &ctx, std::nullptr_t) noexcept;
template <typename T, template <typename T,
typename = std::enable_if_t<std::is_same<T, void>::value>> typename = std::enable_if_t<std::is_same<T, void>::value>>
LIBIMP_EXPORT bool to_string(fmt_context &ctx, T const volatile *a) noexcept; 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; LIBIMP_EXPORT bool to_string(fmt_context &ctx, std::tm const &a, span<char const> fstr = {}) noexcept;
namespace detail { namespace detail {
/** /**
* @brief Convert std::time_t to std::string. * \brief Convert std::time_t to std::string.
* @return an empty string if the conversion fails * \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 { inline bool time_to_string(fmt_context &ctx, std::time_t tt, span<char const> fstr) noexcept {
#if defined(LIBIMP_CC_MSVC) #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 {}; std::tm tm {};
if (::localtime_s(&tm, &tt) != 0) { if (::localtime_s(&tm, &tt) != 0) {
return {}; 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 { namespace detail {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/fmt_cpo.h * \file libimp/fmt_cpo.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief String formatting CPO. * \brief String formatting CPO.
* @date 2022-11-28 * \date 2022-11-28
*/ */
#pragma once #pragma once
@ -18,7 +18,7 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief The context of fmt. * \brief The context of fmt.
*/ */
class LIBIMP_EXPORT fmt_context { class LIBIMP_EXPORT fmt_context {
std::string &joined_; 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 { namespace detail {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/generic.h * \file libimp/generic.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Tools for generic programming. * \brief Tools for generic programming.
* @date 2022-03-01 * \date 2022-03-01
*/ */
#pragma once #pragma once
@ -14,15 +14,15 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief Utility metafunction that maps a sequence of any types to the type void * \brief Utility metafunction that maps a sequence of any types to the type void
* @see https://en.cppreference.com/w/cpp/types/void_t * \see https://en.cppreference.com/w/cpp/types/void_t
*/ */
template <typename...> template <typename...>
using void_t = void; using void_t = void;
/** /**
* @brief A general pattern for supporting customisable functions * \brief A general pattern for supporting customisable functions
* @see https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/p1895r0.pdf * \see https://www.open-std.org/jtc1/sc22/WG21/docs/papers/2019/p1895r0.pdf
*/ */
namespace detail { namespace detail {
@ -42,8 +42,8 @@ struct tag_invoke_t {
constexpr detail::tag_invoke_t tag_invoke {}; constexpr detail::tag_invoke_t tag_invoke {};
/** /**
* @brief Circumventing forwarding reference may override copy and move constructs. * \brief Circumventing forwarding reference may override copy and move constructs.
* @see https://mpark.github.io/programming/2014/06/07/beware-of-perfect-forwarding-constructors/ * \see https://mpark.github.io/programming/2014/06/07/beware-of-perfect-forwarding-constructors/
*/ */
namespace detail { namespace detail {

View File

@ -1,7 +1,7 @@
/** /**
* @file libimp/horrible_cast.h * \file libimp/horrible_cast.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @date 2022-04-17 * \date 2022-04-17
*/ */
#pragma once #pragma once

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/log.h * \file libimp/log.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Simple log output component. * \brief Simple log output component.
* @date 2022-05-22 * \date 2022-05-22
*/ */
#pragma once #pragma once
@ -39,7 +39,7 @@ struct context {
LIBIMP_EXPORT std::string to_string(context &&) noexcept; LIBIMP_EXPORT std::string to_string(context &&) noexcept;
LIBIMP_EXPORT bool to_string(fmt_context &ctx, 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> template <typename T>
bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, context &&arg) noexcept { bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, context &&arg) noexcept {
return ::LIBIMP::log::to_string(ctx, std::move(arg)); return ::LIBIMP::log::to_string(ctx, std::move(arg));
@ -121,7 +121,7 @@ public:
printer() noexcept = default; printer() noexcept = default;
template <typename T, 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>> typename = std::enable_if_t<!std::is_same<printer, T>::value>>
printer(T &p) noexcept printer(T &p) noexcept
: objp_ (static_cast<void *>(&p)) : objp_ (static_cast<void *>(&p))
@ -131,17 +131,17 @@ public:
void output(context) noexcept; void output(context) noexcept;
}; };
/// @brief Standard console output. /// \brief Standard console output.
class LIBIMP_EXPORT std_t { class LIBIMP_EXPORT std_t {
public: public:
void output(log::level, std::string &&) noexcept; void output(log::level, std::string &&) noexcept;
}; };
/// @brief Standard console output object. /// \brief Standard console output object.
LIBIMP_EXPORT extern std_t std_out; LIBIMP_EXPORT extern std_t std_out;
/** /**
* @brief Log information grips. * \brief Log information grips.
*/ */
class grip { class grip {
printer printer_; printer printer_;
@ -160,7 +160,7 @@ class grip {
fmt(std::forward<A>(args)...), fmt(std::forward<A>(args)...),
}; };
} LIBIMP_CATCH(std::exception const &e) { } 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 = { ctx = {
level::failed, std::chrono::system_clock::now(), func_, e.what(), level::failed, std::chrono::system_clock::now(), func_, e.what(),
}; };

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/nameof.h * \file libimp/nameof.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Gets the name string of a type. * \brief Gets the name string of a type.
* @date 2022-11-26 * \date 2022-11-26
*/ */
#pragma once #pragma once
@ -16,20 +16,20 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief The conventional way to obtain demangled symbol name. * \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 * \see https://www.boost.org/doc/libs/1_80_0/libs/core/doc/html/core/demangle.html
* *
* @param name the mangled name * \param name the mangled name
* @return std::string a human-readable demangled type name * \return std::string a human-readable demangled type name
*/ */
std::string demangle(span<char const> name) noexcept; std::string demangle(span<char const> name) noexcept;
/** /**
* @brief Returns an implementation defined string containing the name of the type. * \brief Returns an implementation defined string containing the name of the type.
* @see https://en.cppreference.com/w/cpp/types/type_info/name * \see https://en.cppreference.com/w/cpp/types/type_info/name
* *
* @tparam T a type * \tparam T a type
* @return std::string a human-readable demangled type name * \return std::string a human-readable demangled type name
*/ */
template <typename T> template <typename T>
std::string nameof() noexcept { std::string nameof() noexcept {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/pimpl.h * \file libimp/pimpl.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Pointer To Implementation (pImpl) idiom * \brief Pointer To Implementation (pImpl) idiom
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once

View File

@ -1,13 +1,14 @@
/** /**
* @file libimp/result.h * \file libimp/result.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the return value type with a status code * \brief Define the return value type with a status code
* @date 2022-04-17 * \date 2022-04-17
*/ */
#pragma once #pragma once
#include <type_traits> #include <type_traits>
#include <string> #include <string>
#include <tuple>
#include <cstdint> #include <cstdint>
#include "libimp/def.h" #include "libimp/def.h"
@ -18,10 +19,10 @@
LIBIMP_NAMESPACE_BEG_ 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, * a 64-bit unsigned integer to indicate success or failure,
* so the data significant bit cannot exceed 63 bits. * so the data significant bit cannot exceed 63 bits.
*/ */
@ -62,7 +63,7 @@ namespace detail_result {
template <typename T> template <typename T>
struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> { 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 { constexpr static void init_code(result_code &code) noexcept {
code = {}; code = {};
} }
@ -73,17 +74,17 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
init_code(code, true, value); init_code(code, true, value);
} }
/// @brief Custom default value. /// \brief Custom default value.
constexpr static T default_value() noexcept { constexpr static T default_value() noexcept {
return 0; return 0;
} }
/// @brief Custom type conversions. /// \brief Custom type conversions.
constexpr static T cast_from_code(result_code code) noexcept { constexpr static T cast_from_code(result_code code) noexcept {
return static_cast<T>(code.value()); return static_cast<T>(code.value());
} }
/// @brief Custom formatted output. /// \brief Custom formatted output.
static std::string format(result<T> const &r) noexcept { static std::string format(result<T> const &r) noexcept {
return fmt(*r); return fmt(*r);
} }
@ -91,7 +92,7 @@ struct default_traits<T, std::enable_if_t<std::is_integral<T>::value>> {
template <typename T> template <typename T>
struct default_traits<T, std::enable_if_t<std::is_pointer<T>::value>> { 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 { constexpr static void init_code(result_code &code, T value = default_value()) noexcept {
code = {default_value() != value, reinterpret_cast<result_type>(value)}; 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}; code = {false, r};
} }
/// @brief Custom default value. /// \brief Custom default value.
constexpr static T default_value() noexcept { constexpr static T default_value() noexcept {
return nullptr; return nullptr;
} }
/// @brief Custom type conversions. /// \brief Custom type conversions.
constexpr static T cast_from_code(result_code code) noexcept { constexpr static T cast_from_code(result_code code) noexcept {
return code.ok() ? reinterpret_cast<T>(code.value()) : default_value(); 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 { static std::string format(result<T> const &r) noexcept {
if LIBIMP_LIKELY(r) { if LIBIMP_LIKELY(r) {
return fmt(static_cast<void *>(*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> template <typename T, typename TypeTraits>
class result : public TypeTraits { class result : public TypeTraits {
/// @brief Internal data is stored using result_code. /// \brief Internal data is stored using result_code.
result_code code_; result_code code_;
public: public:
@ -156,7 +157,7 @@ public:
friend bool operator!=(result const &lhs, result const &rhs) noexcept { return lhs.code_ != rhs.code_; } 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 { namespace detail {
inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, result_code r) { inline bool tag_invoke(decltype(::LIBIMP::fmt_to), fmt_context &ctx, result_code r) {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/span.h * \file libimp/span.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Describes an object that can refer to a contiguous sequence of objects * \brief Describes an object that can refer to a contiguous sequence of objects
* @date 2022-10-16 * \date 2022-10-16
*/ */
#pragma once #pragma once
@ -28,7 +28,7 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
namespace detail { namespace detail {
/// @brief Helper trait for span. /// \brief Helper trait for span.
template <typename From, typename To> template <typename From, typename To>
using array_convertible = std::is_convertible<From(*)[], 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>()), typename std::enable_if<std::is_convertible<decltype(std::declval<S>() - std::declval<I>()),
std::ptrdiff_t>::value>::type; 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. /// 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> template<typename T>
constexpr T *to_address(T *ptr) noexcept { constexpr T *to_address(T *ptr) noexcept {
@ -76,8 +76,8 @@ constexpr auto to_address(T const &ptr)
} // namespace detail } // namespace detail
/** /**
* @brief A simple implementation of span. * \brief A simple implementation of span.
* @see https://en.cppreference.com/w/cpp/container/span * \see https://en.cppreference.com/w/cpp/container/span
*/ */
template <typename T> template <typename T>
class span { class span {
@ -205,7 +205,7 @@ public:
} }
}; };
/// @brief Support for span equals comparison. /// \brief Support for span equals comparison.
template <typename T, typename U, template <typename T, typename U,
typename = decltype(std::declval<T>() == std::declval<U>())> typename = decltype(std::declval<T>() == std::declval<U>())>
@ -219,9 +219,9 @@ bool operator==(span<T> a, span<U> b) noexcept {
return true; 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. /// 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> template <typename T>
auto make_span(T *arr, std::size_t count) noexcept -> span<T> { auto make_span(T *arr, std::size_t count) noexcept -> span<T> {

View File

@ -1,8 +1,8 @@
/** /**
* @file libimp/system.h * \file libimp/system.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Isolation and encapsulation of system APIs * \brief Isolation and encapsulation of system APIs
* @date 2022-08-07 * \date 2022-08-07
*/ */
#pragma once #pragma once
@ -18,30 +18,30 @@ LIBIMP_NAMESPACE_BEG_
namespace sys { 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 result_code error_no() noexcept;
LIBIMP_EXPORT void error_no(result_code) 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; LIBIMP_EXPORT std::string error_str(result_code) noexcept;
/** /**
* @brief Identifies the operating system error category. * \brief Identifies the operating system error category.
* @see https://en.cppreference.com/w/cpp/error/system_category * \see https://en.cppreference.com/w/cpp/error/system_category
*/ */
LIBIMP_EXPORT error_category const &category() noexcept; LIBIMP_EXPORT error_category const &category() noexcept;
/** /**
* @brief A platform-dependent error code. * \brief A platform-dependent error code.
* @see https://en.cppreference.com/w/cpp/error/error_code * \see https://en.cppreference.com/w/cpp/error/error_code
*/ */
LIBIMP_EXPORT error_code error() noexcept; 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 { enum class info : std::int32_t {
page_size, page_size,

View File

@ -1,8 +1,8 @@
/** /**
* @file libipc/def.h * \file libipc/def.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the trivial configuration information. * \brief Define the trivial configuration information.
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once
@ -15,7 +15,7 @@
LIBIPC_NAMESPACE_BEG_ LIBIPC_NAMESPACE_BEG_
/// @brief Constants. /// \brief Constants.
struct prot { struct prot {
using type = std::uint32_t; using type = std::uint32_t;

View File

@ -1,8 +1,8 @@
/** /**
* @file libipc/shm.h * \file libipc/shm.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the shared memory access interface * \brief Define the shared memory access interface
* @date 2022-04-17 * \date 2022-04-17
*/ */
#pragma once #pragma once
@ -19,32 +19,32 @@ LIBIPC_NAMESPACE_BEG_
struct shm_handle; struct shm_handle;
using shm_t = 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, LIBIMP_EXPORT ::LIBIMP::result<shm_t> shm_open(std::string name,
std::size_t size = 0, std::size_t size = 0,
mode::type = mode::create | mode::open) noexcept; 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; LIBIMP_EXPORT ::LIBIMP::result_code shm_close(shm_t) noexcept;
/// @brief Gets a memory pointer based on the shared memory handle. /// \brief Gets a memory pointer based on the shared memory handle.
/// @return nullptr on failure. /// \return nullptr on failure.
LIBIMP_EXPORT void *shm_get(shm_t) noexcept; LIBIMP_EXPORT void *shm_get(shm_t) noexcept;
/// @brief Gets the memory size based on the shared memory handle. /// \brief Gets the memory size based on the shared memory handle.
/// @return 0 on failure. /// \return 0 on failure.
LIBIMP_EXPORT std::size_t shm_size(shm_t) noexcept; LIBIMP_EXPORT std::size_t shm_size(shm_t) noexcept;
/// @brief Sets the memory size based on the shared memory handle. /// \brief Sets the memory size based on the shared memory handle.
/// @remark [TBD] /// \remark [TBD]
LIBIMP_EXPORT ::LIBIMP::result_code shm_size(shm_t, std::size_t) noexcept; 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. /// \brief Gets the name of the shared memory file based on the shared memory handle.
/// @return empty string on failure. /// \return empty string on failure.
LIBIMP_EXPORT std::string shm_name(shm_t) noexcept; LIBIMP_EXPORT std::string shm_name(shm_t) noexcept;
/** /**
* @brief The shared memory object. * \brief The shared memory object.
*/ */
class LIBIMP_EXPORT shared_memory { class LIBIMP_EXPORT shared_memory {
shm_t shm_; shm_t shm_;

View File

@ -1,8 +1,8 @@
/** /**
* @file libipc/spin_lock.h * \file libipc/spin_lock.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define spin locks * \brief Define spin locks
* @date 2022-02-27 * \date 2022-02-27
*/ */
#pragma once #pragma once
@ -18,12 +18,12 @@
LIBIPC_NAMESPACE_BEG_ 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; LIBIMP_EXPORT void pause() noexcept;
/** /**
* @brief Yield to other threads * \brief Yield to other threads
*/ */
template <typename K> 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 { class LIBIMP_EXPORT spin_lock {
std::atomic<unsigned> lc_ {0}; 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 { class LIBIMP_EXPORT rw_lock {
std::atomic<unsigned> lc_ {0}; std::atomic<unsigned> lc_ {0};

View File

@ -1,8 +1,8 @@
/** /**
* @file libpmr/allocator.h * \file libpmr/allocator.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief A generic polymorphic memory allocator. * \brief A generic polymorphic memory allocator.
* @date 2022-11-13 * \date 2022-11-13
*/ */
#pragma once #pragma once
@ -19,15 +19,15 @@
LIBPMR_NAMESPACE_BEG_ 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. * 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 * rely on a specific inheritance relationship and only restricts
* the interface behavior of the incoming memory resource object to * the interface behavior of the incoming memory resource object to
* conform to std::pmr::memory_resource. * 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 * https://en.cppreference.com/w/cpp/memory/polymorphic_allocator
*/ */
class LIBIMP_EXPORT allocator { class LIBIMP_EXPORT allocator {
@ -51,8 +51,8 @@ class LIBIMP_EXPORT allocator {
class holder_memory_resource; class holder_memory_resource;
/** /**
* @brief A memory resource pointer holder class for type erasure. * \brief A memory resource pointer holder class for type erasure.
* @tparam MR memory resource type * \tparam MR memory resource type
*/ */
template <typename MR> template <typename MR>
class holder_memory_resource<MR, is_memory_resource<MR>> : public holder_base { 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. * \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 * \tparam MR cannot be converted to the type of memory resource
*/ */
template <typename MR, typename U> template <typename MR, typename U>
class holder_memory_resource : public holder_null { class holder_memory_resource : public holder_null {
@ -100,8 +100,8 @@ public:
allocator(allocator &&other) noexcept; allocator(allocator &&other) noexcept;
allocator &operator=(allocator &&other) & noexcept; allocator &operator=(allocator &&other) & noexcept;
/// @brief Constructs a allocator from a memory resource pointer /// \brief Constructs a allocator from a memory resource pointer
/// @remark The lifetime of the pointer must be longer than that of allocator. /// The lifetime of the pointer must be longer than that of allocator.
template <typename T, typename = is_memory_resource<T>> template <typename T, typename = is_memory_resource<T>>
allocator(T *p_mr) : allocator() { allocator(T *p_mr) : allocator() {
if (p_mr == nullptr) return; if (p_mr == nullptr) return;
@ -112,7 +112,7 @@ public:
bool valid() const noexcept; bool valid() const noexcept;
explicit operator bool() const noexcept; explicit operator bool() const noexcept;
/// @brief Allocate/deallocate memory. /// \brief Allocate/deallocate memory.
void *alloc(std::size_t s); void *alloc(std::size_t s);
void free (void *p, std::size_t s); void free (void *p, std::size_t s);
}; };

View File

@ -1,8 +1,8 @@
/** /**
* @file libpmr/def.h * \file libpmr/def.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Define the trivial configuration information for memory resources. * \brief Define the trivial configuration information for memory resources.
* @date 2022-11-13 * \date 2022-11-13
*/ */
#pragma once #pragma once
@ -12,6 +12,6 @@
LIBPMR_NAMESPACE_BEG_ LIBPMR_NAMESPACE_BEG_
/// @brief Constants. /// \brief Constants.
LIBPMR_NAMESPACE_END_ LIBPMR_NAMESPACE_END_

View File

@ -1,8 +1,8 @@
/** /**
* @file libpmr/memory_resource.h * \file libpmr/memory_resource.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
* @brief Implement memory allocation strategies that can be used by pmr::allocator. * \brief Implement memory allocation strategies that can be used by pmr::allocator.
* @date 2022-11-13 * \date 2022-11-13
*/ */
#pragma once #pragma once
@ -14,7 +14,7 @@
LIBPMR_NAMESPACE_BEG_ LIBPMR_NAMESPACE_BEG_
/// @brief Helper trait for memory resource. /// \brief Helper trait for memory resource.
template <typename T, typename = void> template <typename T, typename = void>
struct has_allocate : std::false_type {}; struct has_allocate : std::false_type {};
@ -40,23 +40,23 @@ using is_memory_resource =
has_deallocate<T>::value>::type; 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. * 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 { class LIBIMP_EXPORT new_delete_resource {
public: 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; static new_delete_resource *get() noexcept;
/// @brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment. /// \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. /// \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 /// \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; void *allocate(std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
/// @brief Deallocates the storage pointed to by p. /// \brief Deallocates the storage pointed to by p.
/// @see https://en.cppreference.com/w/cpp/memory/memory_resource/deallocate /// \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; void deallocate(void *p, std::size_t bytes, std::size_t alignment = alignof(std::max_align_t)) noexcept;
}; };

View File

@ -15,19 +15,19 @@
LIBIMP_NAMESPACE_BEG_ 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. * Modified from UnicodeConverter.
* Copyright (c) 2010. Jianhui Qin (http://blog.csdn.net/jhqin). * Copyright (c) 2010. Jianhui Qin (http://blog.csdn.net/jhqin).
* *
* @remarks codecvt_utf8_utf16/std::wstring_convert is deprecated. * \remarks codecvt_utf8_utf16/std::wstring_convert is deprecated.
* @see https://codingtidbit.com/2020/02/09/c17-codecvt_utf8-is-deprecated/ * \see https://codingtidbit.com/2020/02/09/c17-codecvt_utf8-is-deprecated/
* https://stackoverflow.com/questions/42946335/deprecated-header-codecvt-replacement * https://stackoverflow.com/questions/42946335/deprecated-header-codecvt-replacement
* https://en.cppreference.com/w/cpp/locale/codecvt/in * https://en.cppreference.com/w/cpp/locale/codecvt/in
*/ */
namespace { namespace {
/// @brief X-bit unicode transformation format /// \brief X-bit unicode transformation format
enum class ufmt { enum class ufmt {
utf8, utf8,
utf16, utf16,
@ -53,7 +53,7 @@ template <typename T, ufmt Fmt>
constexpr bool utf_compatible_v = utf_compatible<T, Fmt>::value; 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> template <typename T, typename U>
auto cvt_char(T src, U* des, std::size_t dlen) noexcept 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> template <typename T, typename U>
auto cvt_char(T const *src, std::size_t slen, U &des) noexcept 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> template <typename T, typename U>
auto cvt_char(T src, U *des, std::size_t dlen) noexcept 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> template <typename T, typename U>
auto cvt_char(T const *src, std::size_t slen, U &des) 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> template <typename T, typename U>
auto cvt_char(T src, U *des, std::size_t dlen) noexcept 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> template <typename T, typename U>
auto cvt_char(T const *src, std::size_t slen, U &des) 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> template <typename T, typename U>
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept 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> template <typename T, typename U>
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept 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> template <typename T, typename U>
auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept auto cvt_cstr_utf(T const *src, std::size_t slen, U *des, std::size_t dlen) noexcept

View File

@ -14,8 +14,8 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief Format conversions helpers. * \brief Format conversions helpers.
* @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
* https://en.cppreference.com/w/cpp/io/c/fprintf * https://en.cppreference.com/w/cpp/io/c/fprintf
*/ */
namespace { namespace {
@ -149,7 +149,7 @@ span<char> fmt_context_sbuf() noexcept {
} // namespace } // namespace
/// @brief The context of fmt. /// \brief The context of fmt.
fmt_context::fmt_context(std::string &j) noexcept fmt_context::fmt_context(std::string &j) noexcept
: joined_(j) : joined_(j)
@ -189,7 +189,7 @@ span<char> fmt_context::buffer(std::size_t sz) noexcept {
if ((offset_ + sz) < sbuf.size()) { if ((offset_ + sz) < sbuf.size()) {
return sbuf.subspan(offset_); return sbuf.subspan(offset_);
} else { } else {
/// @remark switch the cache to std::string /// \remark switch the cache to std::string
joined_.assign(sbuf.data(), offset_); joined_.assign(sbuf.data(), offset_);
joined_.resize(roundup(offset_ + sz)); joined_.resize(roundup(offset_ + sz));
} }
@ -216,7 +216,7 @@ bool fmt_context::append(std::string const &str) noexcept {
return true; return true;
} }
/// @brief To string conversion. /// \brief To string conversion.
bool to_string(fmt_context &ctx, char const *a) noexcept { bool to_string(fmt_context &ctx, char const *a) noexcept {
return to_string(ctx, a, {}); return to_string(ctx, a, {});

View File

@ -1,6 +1,6 @@
/** /**
* @file libimp/platform/gnuc/demangle.h * \file libimp/platform/gnuc/demangle.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -15,15 +15,15 @@
LIBIMP_NAMESPACE_BEG_ LIBIMP_NAMESPACE_BEG_
/** /**
* @brief The conventional way to obtain demangled symbol name. * \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 * \see https://www.boost.org/doc/libs/1_80_0/libs/core/doc/html/core/demangle.html
* *
* @param name the mangled name * \param name the mangled name
* @return std::string a human-readable demangled type name * \return std::string a human-readable demangled type name
*/ */
std::string demangle(span<char const> name) noexcept { std::string demangle(span<char const> name) noexcept {
LIBIMP_LOG_(); 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; std::size_t sz = name.size() + 1;
char *buffer = static_cast<char *>(std::malloc(sz)); char *buffer = static_cast<char *>(std::malloc(sz));
int status = 0; int status = 0;

View File

@ -1,6 +1,6 @@
/** /**
* @file libimp/platform/posix/system.h * \file libimp/platform/posix/system.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -19,7 +19,7 @@ namespace sys {
#endif #endif
/** /**
* @brief Get the system error number * \brief Get the system error number
* https://man7.org/linux/man-pages/man3/errno.3.html * https://man7.org/linux/man-pages/man3/errno.3.html
*/ */
result_code error_no() noexcept { 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 * https://man7.org/linux/man-pages/man3/errno.3.html
*/ */
void error_no(result_code code) noexcept { 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://man7.org/linux/man-pages/man3/strerror_l.3.html
* https://manpages.ubuntu.com/manpages/xenial/en/man3/strerror.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/man2/getpagesize.2.html
* https://man7.org/linux/man-pages/man3/sysconf.3.html * https://man7.org/linux/man-pages/man3/sysconf.3.html
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* @file libimp/platform/win/codecvt.h * \file libimp/platform/win/codecvt.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -14,7 +14,7 @@
LIBIMP_NAMESPACE_BEG_ 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 * https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte
* *
* CP_ACP : The system default Windows ANSI code page. * 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), * There is no ut to guarantee correctness (I'm a little lazy here),
* so if there are any bugs, please contact me in time. * so if there are any bugs, please contact me in time.

View File

@ -1,6 +1,6 @@
/** /**
* @file libimp/platform/win/demangle.h * \file libimp/platform/win/demangle.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once

View File

@ -1,6 +1,6 @@
/** /**
* @file libimp/platform/win/system.h * \file libimp/platform/win/system.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -21,7 +21,7 @@ LIBIMP_NAMESPACE_BEG_
namespace sys { 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 * https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror
*/ */
result_code error_no() noexcept { 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 * https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror
*/ */
void error_no(result_code code) noexcept { 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 * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-formatmessage
*/ */
std::string error_str(result_code code) noexcept { 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-getsysteminfo
* https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo * https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getnativesysteminfo
*/ */

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/posix/mmap.h * \file libipc/platform/posix/mmap.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/posix/shm_impl.h * \file libipc/platform/posix/shm_impl.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -54,7 +54,7 @@ result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
return {}; return {};
} }
/// @brief Open the object for read-write access. /// \brief Open the object for read-write access.
int flag = O_RDWR; int flag = O_RDWR;
switch (type) { switch (type) {
case mode::open: case mode::open:
@ -73,7 +73,7 @@ result<int> shm_open_fd(std::string const &name, mode::type type) noexcept {
return {}; 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 | return ::shm_open(name.c_str(), flag, S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP | S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH); 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 { result_code ftruncate_fd(int fd, std::size_t size) noexcept {
LIBIMP_LOG_(); 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) { if (::ftruncate(fd, size) != posix::succ) {
auto err = sys::error(); auto err = sys::error();
log.error("failed: ftruncate(", fd, ", ", size, "). error = ", err); log.error("failed: ftruncate(", fd, ", ", size, "). error = ", err);
@ -93,7 +93,7 @@ result_code ftruncate_fd(int fd, std::size_t size) noexcept {
} // namespace } // 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/man3/fstat.3p.html
* https://man7.org/linux/man-pages/man2/mmap.2.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); 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; struct stat st;
if (::fstat(*fd, &st) == posix::failed) { if (::fstat(*fd, &st) == posix::failed) {
log.error("failed: fstat(fd = ", *fd, "). error = ", sys::error()); log.error("failed: fstat(fd = ", *fd, "). error = ", sys::error());
return {}; return {};
} }
/// @brief Truncate this fd to a specified length /// \brief Truncate this fd to a specified length
if (size == 0) { if (size == 0) {
size = static_cast<std::size_t>(st.st_size); size = static_cast<std::size_t>(st.st_size);
if (!ftruncate_fd(*fd, size)) return {}; if (!ftruncate_fd(*fd, size)) return {};
} else if (st.st_size > 0) { } 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); size = static_cast<std::size_t>(st.st_size);
} else { // st.st_size <= 0 } else { // st.st_size <= 0
if (!ftruncate_fd(*fd, size)) return {}; 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); void *mem = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
if (mem == MAP_FAILED) { if (mem == MAP_FAILED) {
log.error("failed: mmap(size = ", size, ", fd = ", *fd, "). error = ", sys::error()); 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 { result_code shm_close(shm_t h) noexcept {
LIBIMP_LOG_(); 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); log.error("failed: munmap(", shm->memp, ", ", shm->f_sz, "). error = ", err);
return err.code(); return err.code();
} }
/// @brief no unlink the file. /// \brief no unlink the file.
delete shm; delete shm;
return {posix::succ}; return {posix::succ};
} }

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/win/get_sa.h * \file libipc/platform/win/get_sa.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -15,8 +15,8 @@ LIBIPC_NAMESPACE_BEG_
namespace detail { namespace detail {
/** /**
* @brief Create a SECURITY_ATTRIBUTES structure singleton * \brief Create a SECURITY_ATTRIBUTES structure singleton
* @see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85) * \see https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa379560(v=vs.85)
*/ */
inline LPSECURITY_ATTRIBUTES get_sa() { inline LPSECURITY_ATTRIBUTES get_sa() {
static struct initiator { static struct initiator {

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/win/mmap_impl.h * \file libipc/platform/win/mmap_impl.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once
@ -30,8 +30,8 @@ struct shm_handle {
namespace { namespace {
/** /**
* @brief Closes an open object handle. * \brief Closes an open object handle.
* @see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle * \see https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle
*/ */
result_code mmap_close(HANDLE h) { result_code mmap_close(HANDLE h) {
LIBIMP_LOG_(); 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 * https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga
* *
* @param file Specifies the name of the 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. * \param size Specifies the size required to create a file mapping object.
* This size is ignored when opening an existing 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 { result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type type) noexcept {
LIBIMP_LOG_(); LIBIMP_LOG_();
@ -72,7 +72,7 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
return {}; return {};
} }
/// @brief Opens a named file mapping object. /// \brief Opens a named file mapping object.
auto try_open = [&]() -> result<HANDLE> { auto try_open = [&]() -> result<HANDLE> {
HANDLE h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, t_name.c_str()); HANDLE h = ::OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, t_name.c_str());
if (h == NULL) { if (h == NULL) {
@ -83,10 +83,10 @@ result<HANDLE> mmap_open(std::string const &file, std::size_t size, mode::type t
return h; 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> { auto try_create = [&]() -> result<HANDLE> {
HANDLE h = ::CreateFileMapping(INVALID_HANDLE_VALUE, detail::get_sa(), PAGE_READWRITE | SEC_COMMIT, 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()); 0, static_cast<DWORD>(size), t_name.c_str());
if (h == NULL) { if (h == NULL) {
auto err = sys::error(); 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) { if (type == mode::open) {
return try_open(); return try_open();
} else if ((type == (mode::create | mode::open)) && (size == 0)) { } else if ((type == (mode::create | mode::open)) && (size == 0)) {
/// @remark CreateFileMapping may returns ERROR_INVALID_PARAMETER when dwMaximumSizeLow is zero. /// \remark CreateFileMapping may returns ERROR_INVALID_PARAMETER when dwMaximumSizeLow is zero.
/// @see CreateFileMapping (Windows CE 5.0) /// \see CreateFileMapping (Windows CE 5.0)
/// https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa517331(v=msdn.10) /// https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa517331(v=msdn.10)
return try_open(); return try_open();
} else if (!(type & mode::create)) { } 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(); auto h = try_create();
if (!h) return h; 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. /// (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.
if ((type == mode::create) && (::GetLastError() == ERROR_ALREADY_EXISTS)) { if ((type == mode::create) && (::GetLastError() == ERROR_ALREADY_EXISTS)) {
log.info("the file being created already exists. file = ", file, ", type = ", type); 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. * \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 * \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile
*/ */
result<LPVOID> mmap_memof(HANDLE h) { result<LPVOID> mmap_memof(HANDLE h) {
LIBIMP_LOG_(); 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. * \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 * \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualquery
*/ */
result<SIZE_T> mmap_sizeof(LPCVOID mem) { result<SIZE_T> mmap_sizeof(LPCVOID mem) {
LIBIMP_LOG_(); 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. * \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 * \see https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-unmapviewoffile
*/ */
result_code mmap_release(HANDLE h, LPCVOID mem) { result_code mmap_release(HANDLE h, LPCVOID mem) {
LIBIMP_LOG_(); LIBIMP_LOG_();

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/win/shm_impl.h * \file libipc/platform/win/shm_impl.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once

View File

@ -1,6 +1,6 @@
/** /**
* @file libipc/platform/win/to_tchar.h * \file libipc/platform/win/to_tchar.h
* @author mutouyun (orz@orzz.org) * \author mutouyun (orz@orzz.org)
*/ */
#pragma once #pragma once

View File

@ -12,7 +12,7 @@
LIBIPC_NAMESPACE_BEG_ 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 { void *shm_get(shm_t h) noexcept {
LIBIMP_LOG_(); LIBIMP_LOG_();
@ -44,7 +44,7 @@ std::string shm_name(shm_t h) noexcept {
return shm->file; return shm->file;
} }
/// @brief The shared memory object. /// \brief The shared memory object.
shared_memory::shared_memory() noexcept shared_memory::shared_memory() noexcept
: shm_(nullptr) {} : shm_(nullptr) {}

View File

@ -10,29 +10,29 @@ LIBIPC_NAMESPACE_BEG_
#if defined(LIBIMP_CC_MSVC) #if defined(LIBIMP_CC_MSVC)
# include <Windows.h> // YieldProcessor # include <Windows.h> // YieldProcessor
/** /**
* @brief Not for intel c++ compiler, so ignore http://software.intel.com/en-us/forums/topic/296168 * \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 * \see http://msdn.microsoft.com/en-us/library/windows/desktop/ms687419(v=vs.85).aspx
*/ */
# define LIBIPC_LOCK_PAUSE_() YieldProcessor() # define LIBIPC_LOCK_PAUSE_() YieldProcessor()
#elif defined(LIBIMP_CC_GNUC) #elif defined(LIBIMP_CC_GNUC)
# if defined(LIBIMP_INSTR_X86_64) # 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 * 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") # define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__("pause")
# elif defined(LIBIMP_INSTR_I64) # 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 * 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") # define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__ ("hint @pause")
# elif defined(LIBIMP_INSTR_ARM) # elif defined(LIBIMP_INSTR_ARM)
/** /**
* @brief ARM Architecture Reference Manuals (YIELD) * \brief ARM Architecture Reference Manuals (YIELD)
* @see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html * \see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html
*/ */
# define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__ ("yield") # define LIBIPC_LOCK_PAUSE_() __asm__ __volatile__ ("yield")
# endif # endif
@ -40,20 +40,20 @@ LIBIPC_NAMESPACE_BEG_
#if !defined(LIBIPC_LOCK_PAUSE_) #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) # define LIBIPC_LOCK_PAUSE_() std::atomic_signal_fence(std::memory_order_seq_cst)
#endif /*!defined(LIBIPC_LOCK_PAUSE_)*/ #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 { void pause() noexcept {
LIBIPC_LOCK_PAUSE_(); LIBIPC_LOCK_PAUSE_();
} }
/** /**
* @brief Basic spin lock * \brief Basic spin lock
*/ */
void spin_lock::lock() noexcept { void spin_lock::lock() noexcept {
@ -66,14 +66,14 @@ void spin_lock::unlock() noexcept {
lc_.store(0, std::memory_order_release); lc_.store(0, std::memory_order_release);
} }
/// @brief Constants for shared mode spin lock /// \brief Constants for shared mode spin lock
enum : unsigned { enum : unsigned {
w_mask = (std::numeric_limits<std::make_signed_t<unsigned>>::max)(), // b 0111 1111 w_mask = (std::numeric_limits<std::make_signed_t<unsigned>>::max)(), // b 0111 1111
w_flag = w_mask + 1, // b 1000 0000 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 { void rw_lock::lock() noexcept {

View File

@ -11,7 +11,7 @@ LIBPMR_NAMESPACE_BEG_
namespace { 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 { bool verify_args(::LIBIMP::log::grip &log, std::size_t bytes, std::size_t alignment) noexcept {
if (bytes == 0) { if (bytes == 0) {
@ -27,9 +27,9 @@ bool verify_args(::LIBIMP::log::grip &log, std::size_t bytes, std::size_t alignm
} // namespace } // 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 { new_delete_resource *new_delete_resource::get() noexcept {
static new_delete_resource mem_res; 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. * \brief Allocates storage with a size of at least bytes bytes, aligned to the specified alignment.
* @remark Alignment shall be a power of two. * 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/ * 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 { void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_(); LIBIMP_LOG_();
@ -51,18 +51,18 @@ void *new_delete_resource::allocate(std::size_t bytes, std::size_t alignment) no
return nullptr; return nullptr;
} }
#if defined(LIBIMP_CPP_17) #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); return std::aligned_alloc(alignment, bytes);
#else #else
if (alignment <= alignof(std::max_align_t)) { 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); return std::malloc(bytes);
} }
#if defined(LIBIMP_OS_WIN) #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); return ::_aligned_malloc(bytes, alignment);
#else // try posix #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; void *p = nullptr;
int ret = ::posix_memalign(&p, alignment, bytes); int ret = ::posix_memalign(&p, alignment, bytes);
if (ret != 0) { 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. * \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. * 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 { void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_(); LIBIMP_LOG_();
@ -93,7 +93,7 @@ void new_delete_resource::deallocate(void *p, std::size_t bytes, std::size_t ali
return; return;
} }
#if defined(LIBIMP_CPP_17) #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); std::free(p);
#else #else
if (alignment <= alignof(std::max_align_t)) { 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; return;
} }
#if defined(LIBIMP_OS_WIN) #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); ::_aligned_free(p);
#else // try posix #else // try posix
::free(p); ::free(p);

View File

@ -1,5 +1,6 @@
#include <sstream> #include <sstream>
#include <cstdint>
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -75,8 +76,10 @@ TEST(result, fmt) {
EXPECT_EQ(imp::fmt(r0), imp::fmt(imp::result_code())); EXPECT_EQ(imp::fmt(r0), imp::fmt(imp::result_code()));
imp::result<int> r1 {false, -123}; imp::result<int> r1 {false, -123};
EXPECT_EQ(imp::fmt(r1), imp::fmt("[fail, value = ", -123, "]")); EXPECT_EQ(imp::fmt(r1), imp::fmt("[fail, value = ", -123, "]"));
imp::result<void *> r2 {&r1}; imp::result<void *> r2 {&r1};
EXPECT_EQ(imp::fmt(r2), imp::fmt("[succ, value = ", (void *)&r1, "]")); EXPECT_EQ(imp::fmt(r2), imp::fmt("[succ, value = ", (void *)&r1, "]"));
int aaa {}; int aaa {};
imp::result<int *> r3 {&aaa}; imp::result<int *> r3 {&aaa};
EXPECT_EQ(imp::fmt(r3), imp::fmt("[succ, value = ", (void *)&aaa, "]")); EXPECT_EQ(imp::fmt(r3), imp::fmt("[succ, value = ", (void *)&aaa, "]"));