Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 26 additions & 16 deletions common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -454,24 +454,9 @@ cc_test(

cc_library(
name = "native_type",
srcs = ["native_type.cc"],
hdrs = ["native_type.h"],
deps = [
"@com_google_absl//absl/base",
"@com_google_absl//absl/base:config",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/meta:type_traits",
"@com_google_absl//absl/strings",
],
)

cc_test(
name = "native_type_test",
srcs = ["native_type_test.cc"],
deps = [
":native_type",
"//internal:testing",
"@com_google_absl//absl/hash:hash_testing",
":typeinfo",
],
)

Expand Down Expand Up @@ -1031,3 +1016,28 @@ cc_test(
"@com_google_protobuf//:protobuf",
],
)

cc_library(
name = "typeinfo",
srcs = ["typeinfo.cc"],
hdrs = ["typeinfo.h"],
deps = [
"@com_google_absl//absl/base",
"@com_google_absl//absl/base:config",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:nullability",
"@com_google_absl//absl/meta:type_traits",
"@com_google_absl//absl/strings",
],
)

cc_test(
name = "typeinfo_test",
srcs = ["typeinfo_test.cc"],
deps = [
":typeinfo",
"//internal:testing",
"@com_google_absl//absl/hash:hash_testing",
"@com_google_absl//absl/strings",
],
)
170 changes: 2 additions & 168 deletions common/native_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,177 +15,11 @@
#ifndef THIRD_PARTY_CEL_CPP_COMMON_NATIVE_TYPE_H_
#define THIRD_PARTY_CEL_CPP_COMMON_NATIVE_TYPE_H_

#include <cstddef>
#include <ostream>
#include <string>
#include <type_traits>
#include <utility>

#include "absl/base/attributes.h"
#include "absl/base/casts.h" // IWYU pragma: keep
#include "absl/base/config.h"
#include "absl/meta/type_traits.h"

#if ABSL_HAVE_FEATURE(cxx_rtti)
#define CEL_INTERNAL_HAVE_RTTI 1
#elif defined(__GNUC__) && defined(__GXX_RTTI)
#define CEL_INTERNAL_HAVE_RTTI 1
#elif defined(_MSC_VER) && defined(_CPPRTTI)
#define CEL_INTERNAL_HAVE_RTTI 1
#elif !defined(__GNUC__) && !defined(_MSC_VER)
#define CEL_INTERNAL_HAVE_RTTI 1
#endif

#ifdef CEL_INTERNAL_HAVE_RTTI
#include <typeinfo>
#endif
#include "common/typeinfo.h"

namespace cel {

template <typename T, typename = void>
struct NativeTypeTraits;

class ABSL_ATTRIBUTE_TRIVIAL_ABI NativeTypeId final {
private:
template <typename, typename = void>
struct HasNativeTypeTraitsId : std::false_type {};

template <typename T>
struct HasNativeTypeTraitsId<T, std::void_t<decltype(NativeTypeTraits<T>::Id(
std::declval<const T&>()))>>
: std::true_type {};

template <typename T>
static constexpr bool HasNativeTypeTraitsIdV =
HasNativeTypeTraitsId<T>::value;

public:
template <typename T>
static NativeTypeId For() {
static_assert(!std::is_pointer_v<T>);
static_assert(std::is_same_v<T, std::decay_t<T>>);
static_assert(!std::is_same_v<NativeTypeId, std::decay_t<T>>);
#ifdef CEL_INTERNAL_HAVE_RTTI
return NativeTypeId(&typeid(T));
#else
// Adapted from Abseil and GTL. I believe this not being const is to ensure
// the compiler does not merge multiple constants with the same value to
// share the same address.
static char rep;
return NativeTypeId(&rep);
#endif
}

// Gets the NativeTypeId for `T` at runtime. Requires that
// `cel::NativeTypeTraits` is defined for `T`.
template <typename T>
static std::enable_if_t<HasNativeTypeTraitsIdV<absl::remove_cvref_t<T>>,
NativeTypeId>
Of(const T& type) noexcept {
static_assert(!std::is_pointer_v<T>);
static_assert(std::is_same_v<T, std::decay_t<T>>);
static_assert(!std::is_same_v<NativeTypeId, std::decay_t<T>>);
return NativeTypeTraits<absl::remove_cvref_t<T>>::Id(type);
}

// Gets the NativeTypeId for `T` at runtime. Requires that
// `cel::NativeTypeTraits` is defined for `T`.
template <typename T>
static std::enable_if_t<
std::conjunction_v<
std::negation<HasNativeTypeTraitsId<absl::remove_cvref_t<T>>>,
std::is_final<absl::remove_cvref_t<T>>>,
NativeTypeId>
Of(const T&) noexcept {
static_assert(!std::is_pointer_v<T>);
static_assert(std::is_same_v<T, std::decay_t<T>>);
static_assert(!std::is_same_v<NativeTypeId, std::decay_t<T>>);
return NativeTypeId::For<absl::remove_cvref_t<T>>();
}

NativeTypeId() = default;
NativeTypeId(const NativeTypeId&) = default;
NativeTypeId(NativeTypeId&&) noexcept = default;
NativeTypeId& operator=(const NativeTypeId&) = default;
NativeTypeId& operator=(NativeTypeId&&) noexcept = default;

std::string DebugString() const;

friend bool operator==(NativeTypeId lhs, NativeTypeId rhs) {
#ifdef CEL_INTERNAL_HAVE_RTTI
return lhs.rep_ == rhs.rep_ ||
(lhs.rep_ != nullptr && rhs.rep_ != nullptr &&
*lhs.rep_ == *rhs.rep_);
#else
return lhs.rep_ == rhs.rep_;
#endif
}

template <typename H>
friend H AbslHashValue(H state, NativeTypeId id) {
#ifdef CEL_INTERNAL_HAVE_RTTI
return H::combine(std::move(state),
id.rep_ != nullptr ? id.rep_->hash_code() : size_t{0});
#else
return H::combine(std::move(state), absl::bit_cast<uintptr_t>(id.rep_));
#endif
}

private:
#ifdef CEL_INTERNAL_HAVE_RTTI
constexpr explicit NativeTypeId(const std::type_info* rep) : rep_(rep) {}

const std::type_info* rep_ = nullptr;
#else
constexpr explicit NativeTypeId(const void* rep) : rep_(rep) {}

const void* rep_ = nullptr;
#endif
};

inline bool operator!=(NativeTypeId lhs, NativeTypeId rhs) {
return !operator==(lhs, rhs);
}

inline std::ostream& operator<<(std::ostream& out, NativeTypeId id) {
return out << id.DebugString();
}

class NativeType final {
public:
// Determines at runtime whether calling the destructor of `T` can be skipped
// when `T` was allocated by a pooling memory manager.
template <typename T>
ABSL_MUST_USE_RESULT static bool SkipDestructor(const T& type) {
if constexpr (std::is_trivially_destructible_v<T>) {
return true;
} else if constexpr (HasNativeTypeTraitsSkipDestructorV<T>) {
return NativeTypeTraits<T>::SkipDestructor(type);
} else {
return false;
}
}

private:
template <typename, typename = void>
struct HasNativeTypeTraitsSkipDestructor : std::false_type {};

template <typename T>
struct HasNativeTypeTraitsSkipDestructor<
T, std::void_t<decltype(NativeTypeTraits<T>::SkipDestructor(
std::declval<const T&>()))>> : std::true_type {};

template <typename T>
static inline constexpr bool HasNativeTypeTraitsSkipDestructorV =
HasNativeTypeTraitsSkipDestructor<T>::value;

NativeType() = delete;
NativeType(const NativeType&) = delete;
NativeType(NativeType&&) = delete;
~NativeType() = delete;
NativeType& operator=(const NativeType&) = delete;
NativeType& operator=(NativeType&&) = delete;
};
using NativeTypeId = TypeInfo;

} // namespace cel

Expand Down
106 changes: 0 additions & 106 deletions common/native_type_test.cc

This file was deleted.

4 changes: 2 additions & 2 deletions common/native_type.cc → common/typeinfo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/native_type.h"
#include "common/typeinfo.h"

#include <cstddef>
#include <cstdint> // IWYU pragma: keep
Expand Down Expand Up @@ -44,7 +44,7 @@ struct FreeDeleter {

} // namespace

std::string NativeTypeId::DebugString() const {
std::string TypeInfo::DebugString() const {
if (rep_ == nullptr) {
return std::string();
}
Expand Down
Loading