Skip to content

Commit

Permalink
InvocableMap and QueryableMap no longer deriver their pointer-to-…
Browse files Browse the repository at this point in the history
…member.

This caused compatability issues with gcc on C++20.

Also, rename usages of JniT to _JniT because of issues with gcc.

#42

Tested: Compiled on Ubuntu and Mac platforms with C++20 using clang and gcc.
PiperOrigin-RevId: 712293981
  • Loading branch information
jwhpryor authored and copybara-github committed Jan 9, 2025
1 parent 87c7148 commit ba99e90
Show file tree
Hide file tree
Showing 15 changed files with 155 additions and 125 deletions.
14 changes: 7 additions & 7 deletions implementation/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ template <typename JniT_, IdType kIdType_, std::size_t idx,
std::size_t secondary_idx, std::size_t tertiary_idx,
std::size_t ancestry_idx>
struct Id {
using JniT = JniT_;
using _JniT = JniT_;
static constexpr IdType kIdType = kIdType_;

static constexpr auto Class() { return JniT::GetClass(); }
static constexpr auto Class() { return _JniT::GetClass(); }

static constexpr std::size_t kIdx = idx;
static constexpr std::size_t kSecondaryIdx = secondary_idx;
Expand All @@ -58,10 +58,10 @@ struct Id {

template <IdType new_id_type>
using ChangeIdType =
Id<JniT, new_id_type, idx, secondary_idx, tertiary_idx, ancestry_idx>;
Id<_JniT, new_id_type, idx, secondary_idx, tertiary_idx, ancestry_idx>;

template <std::size_t kIdxToChange, std::size_t kNewValue>
using ChangeIdx = Id<JniT, kIdType, (kIdxToChange == 0 ? kNewValue : idx),
using ChangeIdx = Id<_JniT, kIdType, (kIdxToChange == 0 ? kNewValue : idx),
(kIdxToChange == 1 ? kNewValue : secondary_idx),
(kIdxToChange == 2 ? kNewValue : tertiary_idx),
(kIdxToChange == 3 ? kNewValue : ancestry_idx)>;
Expand Down Expand Up @@ -148,7 +148,7 @@ struct Id {
}
}

using ParentIdT = Id<typename JniT::ParentJniT, kIdType_, idx, secondary_idx,
using ParentIdT = Id<typename _JniT::ParentJniT, kIdType_, idx, secondary_idx,
tertiary_idx, ancestry_idx - 1>;

static constexpr auto Val() {
Expand Down Expand Up @@ -199,7 +199,7 @@ struct Id {
} else if constexpr (kIdType == IdType::STATIC_OVERLOAD_SET) {
return Val().name_;
} else if constexpr (kIdType == IdType::STATIC_OVERLOAD) {
return Id<JniT, IdType::STATIC_OVERLOAD_SET, idx, secondary_idx,
return Id<_JniT, IdType::STATIC_OVERLOAD_SET, idx, secondary_idx,
tertiary_idx, ancestry_idx>::Name();
} else if constexpr (kIdType == IdType::STATIC_FIELD) {
return std::get<idx>(Class().static_.fields_).name_;
Expand All @@ -208,7 +208,7 @@ struct Id {
} else if constexpr (kIdType == IdType::OVERLOAD_SET) {
return Val().name_;
} else if constexpr (kIdType == IdType::OVERLOAD) {
return Id<JniT, IdType::OVERLOAD_SET, idx, secondary_idx, tertiary_idx,
return Id<_JniT, IdType::OVERLOAD_SET, idx, secondary_idx, tertiary_idx,
ancestry_idx>::Name();
} else if constexpr (kIdType == IdType::FIELD) {
return std::get<idx>(Class().fields_).name_;
Expand Down
6 changes: 3 additions & 3 deletions implementation/local_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class LocalArray
using RawValT = std::conditional_t<std::is_same_v<jobject, SpanType>,
std::decay_t<decltype(kClass)>, SpanType>;

using JniT_ = JniT<SpanType, class_v_, class_loader_v_, jvm_v_, kRank_>;
using _JniT = JniT<SpanType, class_v_, class_loader_v_, jvm_v_, kRank_>;

using Base =
ArrayRef<JniT<SpanType, class_v_, class_loader_v_, jvm_v_, kRank_>>;
Expand All @@ -68,7 +68,7 @@ class LocalArray
LocalArray(std::size_t size, RefTag arr)
: Base(AdoptLocal{}, JniArrayHelper<jobject, kRank_>::NewArray(
size,
ClassRef_t<JniT_>::GetAndMaybeLoadClassRef(
ClassRef_t<_JniT>::GetAndMaybeLoadClassRef(
static_cast<jobject>(arr)),
arr)) {}

Expand Down Expand Up @@ -103,7 +103,7 @@ class LocalArray
const ObjectContainer<class_v, class_loader_v, jvm_v>& local_object)
: Base(JniArrayHelper<jobject, kRank_>::NewArray(
size,
ClassRef_t<JniT_>::GetAndMaybeLoadClassRef(
ClassRef_t<_JniT>::GetAndMaybeLoadClassRef(
static_cast<jobject>(local_object)),
static_cast<jobject>(local_object))) {}

Expand Down
11 changes: 6 additions & 5 deletions implementation/method_selection.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ template <typename IdT_, IdType kIDType = IdType::OVERLOAD,
IdType kReturnIDType = IdType::OVERLOAD_PARAM>
struct MethodSelection {
using IdT = IdT_;
using JniT = typename IdT::JniT;
using _JniT = typename IdT::_JniT;

template <std::size_t I, typename... Ts>
struct Helper {
using type = metaprogramming::Val_t<OverloadSelection<
Id<JniT, kIDType, IdT::kIdx, I, kNoIdx, 0>,
Id<_JniT, kIDType, IdT::kIdx, I, kNoIdx, 0>,
kReturnIDType>::template OverloadIdxIfViable<Ts...>()>;
};

Expand All @@ -103,7 +103,8 @@ struct MethodSelection {

template <typename... Ts>
using FindOverloadSelection = OverloadSelection<
Id<JniT, kIDType, IdT::kIdx, kIdxForTs<Ts...>, kNoIdx, 0>, kReturnIDType>;
Id<_JniT, kIDType, IdT::kIdx, kIdxForTs<Ts...>, kNoIdx, 0>,
kReturnIDType>;

template <typename... Ts>
static constexpr bool ArgSetViable() {
Expand All @@ -116,8 +117,8 @@ struct OverloadSelector {
using OverloadSelectionForArgs = typename MethodSelection<
IdT, kIDType, kReturnIDType>::template FindOverloadSelection<Args...>;

using OverloadRef =
OverloadRef<Id<typename IdT::JniT, kIDType, IdT::kIdx,
using _OverloadRef =
OverloadRef<Id<typename IdT::_JniT, kIDType, IdT::kIdx,
OverloadSelectionForArgs::IdT::kSecondaryIdx, kNoIdx, 0>,
kReturnIDType>;

Expand Down
25 changes: 14 additions & 11 deletions implementation/object_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ class ObjectRef
// C++17 augmentations.
: public metaprogramming::InvocableMap<
ObjectRef<JniT>, JniT::stripped_class_v, typename JniT::ClassT,
&JniT::ClassT::methods_>,
decltype(&JniT::ClassT::methods_), &JniT::ClassT::methods_>,
public metaprogramming::QueryableMap_t<
ObjectRef<JniT>, JniT::stripped_class_v, &JniT::ClassT::fields_>,
ObjectRef<JniT>, JniT::stripped_class_v,
decltype(&JniT::ClassT::fields_), &JniT::ClassT::fields_>,
// C++ 20 augmentations.
public metaprogramming::InvocableMap20_t<
ObjectRef<JniT>, JniT::stripped_class_v, &JniT::ClassT::methods_>,
public metaprogramming::QueryableMap20_t<
ObjectRef<JniT>, JniT::stripped_class_v, &JniT::ClassT::fields_>,
public metaprogramming::InvocableMap20<
ObjectRef<JniT>, JniT::stripped_class_v, ObjectRef<JniT>,
decltype(&JniT::ClassT::methods_), &JniT::ClassT::methods_>,
public metaprogramming::QueryableMap20<
ObjectRef<JniT>, JniT::stripped_class_v, ObjectRef<JniT>,
decltype(&JniT::ClassT::fields_), &JniT::ClassT::fields_>,
public RefBase<typename JniT::StorageType> {
protected:
static_assert(
Expand Down Expand Up @@ -109,7 +112,7 @@ class ObjectRef
static_assert(MethodSelectionForArgs::kIsValidArgSet,
"JNI Error: Invalid argument set.");

return MethodSelectionForArgs::OverloadRef::Invoke(
return MethodSelectionForArgs::_OverloadRef::Invoke(
GetJClass(), RefBaseT::object_ref_, std::forward<Args>(args)...);
}

Expand Down Expand Up @@ -139,7 +142,7 @@ class ObjectRef
static_assert(MethodSelectionForArgs::kIsValidArgSet,
"JNI Error: Invalid argument set.");

return MethodSelectionForArgs::OverloadRef::Invoke(
return MethodSelectionForArgs::_OverloadRef::Invoke(
GetJClass(), RefBaseT::object_ref_, std::forward<Args>(args)...);
}

Expand Down Expand Up @@ -187,7 +190,7 @@ class ConstructorValidator : public ObjectRef<JniT> {
int>::type = 0>
ConstructorValidator(Args&&... args)
: Base(static_cast<typename JniT::StorageType>(
Permutation_t<Args...>::OverloadRef::Invoke(
Permutation_t<Args...>::_OverloadRef::Invoke(
Base::GetJClass(), Base::object_ref_,
std::forward<Args>(args)...)
.Release())) {
Expand All @@ -196,8 +199,8 @@ class ConstructorValidator : public ObjectRef<JniT> {
}

ConstructorValidator()
: Base(Permutation_t<>::OverloadRef::Invoke(Base::GetJClass(),
Base::object_ref_)
: Base(Permutation_t<>::_OverloadRef::Invoke(Base::GetJClass(),
Base::object_ref_)
.Release()) {}
};

Expand Down
4 changes: 2 additions & 2 deletions implementation/proxy_definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ struct Proxy<JObject,
template <typename Id>
struct Helper {
static constexpr auto kClass{Id::Val()};
static constexpr auto kClassLoader{Id::JniT::GetClassLoader()};
static constexpr auto kClassLoader{Id::_JniT::GetClassLoader()};

// TODO(b/174272629): Class loaders should also be enforced.
using type = LocalObject<kClass, kClassLoader, kDefaultJvm>;
Expand Down Expand Up @@ -200,7 +200,7 @@ struct Proxy<SelfType,
template <typename Id>
struct Helper {
static constexpr auto kClass{Id::Val()};
static constexpr auto kClassLoader{Id::JniT::GetClassLoader()};
static constexpr auto kClassLoader{Id::_JniT::GetClassLoader()};

// TODO(b/174272629): Class loaders should also be enforced.
using type = LocalObject<kClass, kClassLoader, kDefaultJvm>;
Expand Down
2 changes: 1 addition & 1 deletion implementation/signature_method_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ static constexpr auto Sig_v =
////////////////////////////////////////////////////////////////////////////////
using kSelf1 = Id<JT, IdType::CLASS, kNoIdx, 0, kNoIdx, 0>;
using JniSelfT =
JniTSelector<jni::LocalArray<jobject, 3, kClass1>::JniT_, -1, 0>;
JniTSelector<jni::LocalArray<jobject, 3, kClass1>::_JniT, -1, 0>;
using StaticSelectorInfoSelf = SelectorStaticInfo<JniSelfT>;

static_assert(std::string_view{"LkClass1;"} ==
Expand Down
46 changes: 26 additions & 20 deletions implementation/static_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,28 @@ namespace jni {
template <typename CrtpBase_, const auto& class_v_, const auto& class_loader_v_,
const auto& jvm_v_>
struct StaticRefHelper {
using JniT = JniT<jobject, class_v_, class_loader_v_, jvm_v_>;
using _JniT = JniT<jobject, class_v_, class_loader_v_, jvm_v_>;

// C++17 augmentations.
using MethodMapT = metaprogramming::InvocableMap<CrtpBase_, JniT::static_v,
typename JniT::StaticT,
&JniT::StaticT::methods_>;
using FieldMapT = metaprogramming::QueryableMap_t<CrtpBase_, JniT::static_v,
&JniT::StaticT::fields_>;
using MethodMapT = metaprogramming::InvocableMap<
CrtpBase_, _JniT::static_v, typename _JniT::StaticT,
decltype(&_JniT::StaticT::methods_), &_JniT::StaticT::methods_>;
using FieldMapT =
metaprogramming::QueryableMap_t<CrtpBase_, _JniT::static_v,

decltype(&_JniT::StaticT::fields_),
&_JniT::StaticT::fields_>;

// C++ 20 augmentations.
using MethodMap20T =
metaprogramming::InvocableMap20_t<CrtpBase_, JniT::static_v,
&JniT::StaticT::methods_>;
using FieldMap20T =
metaprogramming::QueryableMap20_t<CrtpBase_, JniT::static_v,
&JniT::StaticT::fields_>;
using MethodMap20T = metaprogramming::InvocableMap20<
CrtpBase_, _JniT::static_v,
StaticRefHelper<CrtpBase_, class_v_, class_loader_v_, jvm_v_>,
decltype(&_JniT::StaticT::methods_), &_JniT::StaticT::methods_>;

using FieldMap20T = metaprogramming::QueryableMap20<
CrtpBase_, _JniT::static_v,
StaticRefHelper<CrtpBase_, class_v_, class_loader_v_, jvm_v_>,
decltype(&_JniT::StaticT::fields_), &_JniT::StaticT::fields_>;
};

// C++17 augmentations.
Expand Down Expand Up @@ -100,10 +106,10 @@ struct StaticRef
class_v_, class_loader_v_, jvm_v_>,
StaticRefHelperFieldMap20_t<StaticRef<class_v_, class_loader_v_, jvm_v_>,
class_v_, class_loader_v_, jvm_v_> {
using JniT = JniT<jobject, class_v_, class_loader_v_, jvm_v_>;
using _JniT = JniT<jobject, class_v_, class_loader_v_, jvm_v_>;

jclass GetJClass() const {
return ClassRef_t<JniT>::GetAndMaybeLoadClassRef(nullptr);
return ClassRef_t<_JniT>::GetAndMaybeLoadClassRef(nullptr);
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -114,21 +120,21 @@ struct StaticRef
#if __clang__
template <size_t I, typename... Args>
auto InvocableMapCall(const char* key, Args&&... args) const {
using IdT = Id<JniT, IdType::STATIC_OVERLOAD_SET, I, kNoIdx, kNoIdx, 0>;
using IdT = Id<_JniT, IdType::STATIC_OVERLOAD_SET, I, kNoIdx, kNoIdx, 0>;
using MethodSelectionForArgs =
OverloadSelector<IdT, IdType::STATIC_OVERLOAD,
IdType::STATIC_OVERLOAD_PARAM, Args...>;

static_assert(MethodSelectionForArgs::kIsValidArgSet,
"JNI Error: Invalid argument set.");

return MethodSelectionForArgs::OverloadRef::Invoke(
return MethodSelectionForArgs::_OverloadRef::Invoke(
GetJClass(), nullptr, std::forward<Args>(args)...);
}

template <size_t I>
auto QueryableMapCall(const char* key) const {
return FieldRef<JniT, IdType::STATIC_FIELD, I>{GetJClass(), nullptr};
return FieldRef<_JniT, IdType::STATIC_FIELD, I>{GetJClass(), nullptr};
}
#endif // __clang__

Expand All @@ -137,22 +143,22 @@ struct StaticRef
template <size_t I, metaprogramming::StringLiteral key_literal,
typename... Args>
auto InvocableMap20Call(Args&&... args) const {
using IdT = Id<JniT, IdType::STATIC_OVERLOAD_SET, I, kNoIdx, kNoIdx, 0>;
using IdT = Id<_JniT, IdType::STATIC_OVERLOAD_SET, I, kNoIdx, kNoIdx, 0>;
using MethodSelectionForArgs =
OverloadSelector<IdT, IdType::STATIC_OVERLOAD,
IdType::STATIC_OVERLOAD_PARAM, Args...>;

static_assert(MethodSelectionForArgs::kIsValidArgSet,
"JNI Error: Invalid argument set.");

return MethodSelectionForArgs::OverloadRef::Invoke(
return MethodSelectionForArgs::_OverloadRef::Invoke(
GetJClass(), nullptr, std::forward<Args>(args)...);
}

// Invoked through CRTP from QueryableMap20, C++20 only.
template <size_t I, metaprogramming::StringLiteral key_literal>
auto QueryableMap20Call() const {
return FieldRef<JniT, IdType::STATIC_FIELD, I>{GetJClass(), nullptr};
return FieldRef<_JniT, IdType::STATIC_FIELD, I>{GetJClass(), nullptr};
}
#endif // __cplusplus >= 202002L
};
Expand Down
37 changes: 16 additions & 21 deletions metaprogramming/invocable_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@

namespace jni::metaprogramming {

template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member>
class InvocableMap;

// This is an interface that can be inherited from to expose an operator(...).
// It provides compile time string index lookup with no macros although it is
// dependent on a clang extension.
Expand All @@ -54,36 +50,38 @@ class InvocableMap;
// the the const char cannot be propagated without losing its constexpr-ness,
// and so the clang extension can no longer restrict function candidates.
template <typename CrtpBase, const auto& tup_container_v,
const auto std::decay_t<decltype(tup_container_v)>::* nameable_member>
using InvocableMap_t =
InvocableMap<CrtpBase, tup_container_v,
std::decay_t<decltype(tup_container_v)>, nameable_member>;
typename TupContainerT, typename MemberT, MemberT nameable_member>
class InvocableMap;

template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member,
typename TupContainerT, typename MemberT, MemberT nameable_member,
std::size_t I>
class InvocableMapEntry;

template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member,
typename TupContainerT, typename MemberT, MemberT nameable_member,
typename IndexSequenceType>
class InvocableMapBase {};

template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member,
typename TupContainerT, typename MemberT, MemberT nameable_member,

std::size_t... idxs>
class InvocableMapBase<CrtpBase, tup_container_v, TupContainerT,
class InvocableMapBase<CrtpBase, tup_container_v, TupContainerT, MemberT,
nameable_member, std::index_sequence<idxs...>>
: public InvocableMapEntry<CrtpBase, tup_container_v, TupContainerT,
nameable_member, idxs>... {
MemberT, nameable_member, idxs>... {
public:
using InvocableMapEntry<CrtpBase, tup_container_v, TupContainerT,
#if __clang__
using InvocableMapEntry<CrtpBase, tup_container_v, TupContainerT, MemberT,
nameable_member, idxs>::
operator()...;
#endif // __clang__
};

template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member,
typename TupContainerT, typename MemberT, MemberT nameable_member,

std::size_t I>
class InvocableMapEntry {
public:
Expand All @@ -109,18 +107,15 @@ class InvocableMapEntry {
.template InvocableMapCall<I, Args...>(key,
std::forward<Args>(args)...);
}
#else
static_assert(false,
"This container requires clang for compile time strings.");
#endif
#endif // __clang__
};

//==============================================================================
template <typename CrtpBase, const auto& tup_container_v,
typename TupContainerT, const auto TupContainerT::* nameable_member>
typename TupContainerT, typename MemberT, MemberT nameable_member>
class InvocableMap
: public InvocableMapBase<
CrtpBase, tup_container_v, TupContainerT, nameable_member,
CrtpBase, tup_container_v, TupContainerT, MemberT, nameable_member,
std::make_index_sequence<std::tuple_size_v<
std::decay_t<decltype(tup_container_v.*nameable_member)>>>> {};

Expand Down
Loading

0 comments on commit ba99e90

Please sign in to comment.