mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
add: [imp] dataof
This commit is contained in:
parent
ce04c79112
commit
07c13f1b3a
92
include/libimp/dataof.h
Normal file
92
include/libimp/dataof.h
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* \file libimp/dataof.h
|
||||
* \author mutouyun (orz@orzz.org)
|
||||
* \brief Returns the data pointer of the given range
|
||||
* \date 2023-05-27
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <type_traits> // std::declval, std::true_type, std::false_type
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
#include "libimp/def.h"
|
||||
#include "libimp/generic.h"
|
||||
|
||||
LIBIMP_NAMESPACE_BEG_
|
||||
|
||||
/**
|
||||
* \see https://en.cppreference.com/w/cpp/iterator/data
|
||||
*/
|
||||
|
||||
namespace detail_dataof {
|
||||
|
||||
template <typename T>
|
||||
struct trait_has_data {
|
||||
private:
|
||||
template <typename Type>
|
||||
static std::true_type check(decltype(std::declval<Type>().data())*);
|
||||
template <typename Type>
|
||||
static std::false_type check(...);
|
||||
public:
|
||||
using type = decltype(check<T>(nullptr));
|
||||
constexpr static auto value = type::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct trait_has_Data {
|
||||
private:
|
||||
template <typename Type>
|
||||
static std::true_type check(decltype(std::declval<Type>().Data())*);
|
||||
template <typename Type>
|
||||
static std::false_type check(...);
|
||||
public:
|
||||
using type = decltype(check<T>(nullptr));
|
||||
constexpr static auto value = type::value;
|
||||
};
|
||||
|
||||
template <typename C, bool = trait_has_data<C>::value
|
||||
, bool = trait_has_Data<C>::value>
|
||||
struct trait;
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct trait<T[N], false, false> {
|
||||
constexpr static T const *dataof(T const (&arr)[N]) noexcept {
|
||||
return arr;
|
||||
}
|
||||
constexpr static T *dataof(T (&arr)[N]) noexcept {
|
||||
return arr;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C, bool B>
|
||||
struct trait<C, true, B> {
|
||||
template <typename T>
|
||||
constexpr static auto dataof(T &&c) noexcept(noexcept(c.data())) {
|
||||
return std::forward<T>(c).data();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct trait<C, false, true> {
|
||||
template <typename T>
|
||||
constexpr static auto dataof(T &&c) noexcept(noexcept(c.Data())) {
|
||||
return std::forward<T>(c).Data();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename C>
|
||||
struct trait<C, false, false> {
|
||||
template <typename T>
|
||||
constexpr static T const *dataof(std::initializer_list<T> il) noexcept {
|
||||
return il.begin();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail_dataof
|
||||
|
||||
template <typename T, typename R = detail_dataof::trait<std::remove_cv_t<std::remove_reference_t<T>>>>
|
||||
constexpr auto dataof(T &&c) noexcept(noexcept(R::dataof(std::forward<T>(c)))) {
|
||||
return R::dataof(std::forward<T>(c));
|
||||
}
|
||||
|
||||
LIBIMP_NAMESPACE_END_
|
||||
@ -8,6 +8,7 @@
|
||||
#include "libimp/construct.h"
|
||||
#include "libimp/pimpl.h"
|
||||
#include "libimp/countof.h"
|
||||
#include "libimp/dataof.h"
|
||||
#include "libimp/horrible_cast.h"
|
||||
#include "libimp/detect_plat.h"
|
||||
#include "libimp/generic.h"
|
||||
@ -100,9 +101,27 @@ TEST(utility, countof) {
|
||||
|
||||
std::vector<int> vec {1, 2, 3, 4, 5};
|
||||
int arr[] {7, 6, 5, 4, 3, 2, 1};
|
||||
auto il = {9, 7, 6, 4, 3, 1, 5};
|
||||
EXPECT_EQ(imp::countof(sv) , sv.Size());
|
||||
EXPECT_EQ(imp::countof(vec), vec.size());
|
||||
EXPECT_EQ(imp::countof(arr), sizeof(arr) / sizeof(arr[0]));
|
||||
EXPECT_EQ(imp::countof(il) , il.size());
|
||||
}
|
||||
|
||||
TEST(utility, dataof) {
|
||||
struct {
|
||||
constexpr int *Data() const noexcept { return (int *)this; }
|
||||
} sv;
|
||||
EXPECT_FALSE(imp::detail_dataof::trait_has_data<decltype(sv)>::value);
|
||||
EXPECT_TRUE (imp::detail_dataof::trait_has_Data<decltype(sv)>::value);
|
||||
|
||||
std::vector<int> vec {1, 2, 3, 4, 5};
|
||||
int arr[] {7, 6, 5, 4, 3, 2, 1};
|
||||
auto il = {9, 7, 6, 4, 3, 1, 5};
|
||||
EXPECT_EQ(imp::dataof(sv) , sv.Data());
|
||||
EXPECT_EQ(imp::dataof(vec), vec.data());
|
||||
EXPECT_EQ(imp::dataof(arr), arr);
|
||||
EXPECT_EQ(imp::dataof(il) , il.begin());
|
||||
}
|
||||
|
||||
TEST(utility, horrible_cast) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user