From 1ff5900a6d197eed89edcceeff9396954ac34ef0 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Tue, 1 Mar 2022 10:59:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4ut=EF=BC=9B=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0utility=E5=B0=8F=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libipc/utility/construct.h | 4 ++-- src/libipc/utility/countof.h | 34 ++++++++++++++++++++++++++++++++++ src/libipc/utility/enum_cast.h | 20 ++++++++++++++++++++ test/test_utility.cpp | 17 ++++++++++------- 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 src/libipc/utility/countof.h create mode 100644 src/libipc/utility/enum_cast.h diff --git a/src/libipc/utility/construct.h b/src/libipc/utility/construct.h index 888cdbd..ad21ffd 100644 --- a/src/libipc/utility/construct.h +++ b/src/libipc/utility/construct.h @@ -45,7 +45,7 @@ auto construct(void *p, A &&... args) template void *destroy(T *p) noexcept { -#if defined(LIBIPC_CPP_17) && !defined(LIBIPC_CC_GNUC) +#if defined(LIBIPC_CPP_17) std::destroy_at(p); #else p->~T(); @@ -57,7 +57,7 @@ template void *destroy(T (*p)[N]) noexcept { #if defined(LIBIPC_CPP_20) std::destroy_at(p); -#elif defined(LIBIPC_CPP_17) && !defined(LIBIPC_CC_GNUC) +#elif defined(LIBIPC_CPP_17) std::destroy(std::begin(*p), std::end(*p)); #else for (auto &elem : *p) destroy(std::addressof(elem)); diff --git a/src/libipc/utility/countof.h b/src/libipc/utility/countof.h new file mode 100644 index 0000000..0fa2dd8 --- /dev/null +++ b/src/libipc/utility/countof.h @@ -0,0 +1,34 @@ +/** + * @file src/countof.h + * @author mutouyun (orz@orzz.org) + * @brief Returns the size of the given range + * @date 2022-03-01 + */ +#pragma once + +#include // std::size_t + +#include "libipc/def.h" + +LIBIPC_NAMESPACE_BEG_ + +/** + * @see https://en.cppreference.com/w/cpp/iterator/size +*/ + +template +constexpr std::size_t countof(T const (&)[N]) noexcept { + return N; +} + +template +constexpr auto countof(C const &c) -> decltype(c.size()) { + return c.size(); +} + +template +constexpr auto countof(C const &c) -> decltype(c.Size()) { + return c.Size(); +} + +LIBIPC_NAMESPACE_END_ diff --git a/src/libipc/utility/enum_cast.h b/src/libipc/utility/enum_cast.h new file mode 100644 index 0000000..23fd65e --- /dev/null +++ b/src/libipc/utility/enum_cast.h @@ -0,0 +1,20 @@ +/** + * @file src/enum_cast.h + * @author mutouyun (orz@orzz.org) + * @brief Returns the underlying type of the given enum + * @date 2022-03-01 + */ +#pragma once + +#include // std::underlying_type_t + +#include "libipc/def.h" + +LIBIPC_NAMESPACE_BEG_ + +template +constexpr auto enum_cast(E e) noexcept { + return static_cast>(e); +} + +LIBIPC_NAMESPACE_END_ diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 8d3751e..d2c3dae 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -6,6 +6,7 @@ #include "libipc/utility/construct.h" #include "libipc/utility/pimpl.h" +#include "libipc/utility/countof.h" TEST(utility, construct) { struct Foo { @@ -20,18 +21,22 @@ TEST(utility, construct) { EXPECT_EQ(pfoo->c_, '1'); ipc::destroy(pfoo); + static int bar_test_flag = 0; struct Bar : Foo { Bar(int a, short b, char c) - : Foo{a, b, c} {} - ~Bar() { a_ = 0; } + : Foo{a, b, c} { + ++bar_test_flag; + } + ~Bar() { --bar_test_flag; } }; std::aligned_storage_t bar; Bar *pbar = ipc::construct(&bar, 123, short(321), '1'); EXPECT_EQ(pbar->a_, 123); EXPECT_EQ(pbar->b_, 321); EXPECT_EQ(pbar->c_, '1'); + EXPECT_EQ(bar_test_flag, 1); ipc::destroy(pbar); - EXPECT_EQ(pbar->a_, 0); + EXPECT_EQ(bar_test_flag, 0); std::aligned_storage_t bars[3]; for (auto &b : bars) { @@ -40,11 +45,9 @@ TEST(utility, construct) { EXPECT_EQ(pb->b_, 123); EXPECT_EQ(pb->c_, '3'); } + EXPECT_EQ(bar_test_flag, ipc::countof(bars)); ipc::destroy(reinterpret_cast(&bars)); - for (auto &b : bars) { - auto pb = reinterpret_cast(&b); - EXPECT_EQ(pb->a_, 0); - } + EXPECT_EQ(bar_test_flag, 0); } namespace {