brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.2 KiB · 767420d Raw
310 lines · cpp
1// RUN: %clang_cc1 -std=c++20 -verify %s2// expected-no-diagnostics3 4template <int __v> struct integral_constant {5  static constexpr int value = __v;6};7template <bool _Val> using _BoolConstant = integral_constant<_Val>;8template <int, class> struct tuple_element;9template <class...> class tuple;10template <int _Ip, class... _Tp> struct tuple_element<_Ip, tuple<_Tp...>> {11  using type = __type_pack_element<_Ip, _Tp...>;12};13template <class> struct tuple_size;14template <bool> using __enable_if_t = int;15template <template <class> class _BaseType, class _Tp, _Tp _SequenceSize>16using __make_integer_sequence_impl =17    __make_integer_seq<_BaseType, _Tp, _SequenceSize>;18template <class _Tp, _Tp...> struct __integer_sequence;19template <int... _Indices>20using __index_sequence = __integer_sequence<int, _Indices...>;21template <int _SequenceSize>22using __make_index_sequence =23    __make_integer_sequence_impl<__integer_sequence, int, _SequenceSize>;24template <class _Tp, _Tp...> struct integer_sequence {};25template <int... _Ip> using index_sequence = integer_sequence<int, _Ip...>;26template <class _Tp, _Tp _Ep>27using make_integer_sequence =28    __make_integer_sequence_impl<integer_sequence, _Tp, _Ep>;29template <int _Np> using make_index_sequence = make_integer_sequence<int, _Np>;30enum __element_count : int;31constexpr void __constexpr_memmove(char *__dest, const char *__src,32                                   __element_count __n) {33  __builtin_memmove(__dest, __src, __n);34}35template <class _Tp> using __underlying_type_t = __underlying_type(_Tp);36template <class _Tp> using underlying_type_t = __underlying_type_t<_Tp>;37template <class _Tp, class> using __enable_if_tuple_size_imp = _Tp;38template <class _Tp>39struct tuple_size<__enable_if_tuple_size_imp<40    const _Tp, __enable_if_t<_BoolConstant<__is_volatile(int)>::value>>>41    : integral_constant<tuple_size<_Tp>::value> {};42template <class... _Tp>43struct tuple_size<tuple<_Tp...>> : integral_constant<sizeof...(_Tp)> {};44template <class _Tp> constexpr int tuple_size_v = tuple_size<_Tp>::value;45template <class _T1, class _T2> struct pair {46  _T1 first;47  _T2 second;48};49template <class _T1> constexpr pair<_T1, char *> make_pair(_T1, char *__t2) {50  return pair(_T1(), __t2);51}52template <int, class _Hp> struct __tuple_leaf {53  _Hp __value_;54  constexpr const _Hp &get() const { return __value_; }55};56template <class...> struct __tuple_impl;57template <int... _Indx, class... _Tp>58struct __tuple_impl<__index_sequence<_Indx...>, _Tp...>59    : __tuple_leaf<_Indx, _Tp>... {60  template <class... _Args>61  constexpr __tuple_impl(int, _Args... __args)62      : __tuple_leaf<_Indx, _Tp>(__args)... {}63};64template <class... _Tp> struct tuple {65  __tuple_impl<__make_index_sequence<sizeof...(_Tp)>, _Tp...> __base_;66  template <class... _Up> constexpr tuple(_Up... __u) : __base_({}, __u...) {}67};68template <int _Ip, class... _Tp>69constexpr const tuple_element<_Ip, tuple<_Tp...>>::type &70get(const tuple<_Tp...> &__t) noexcept {71  return static_cast<const __tuple_leaf<72      _Ip, typename tuple_element<_Ip, tuple<_Tp...>>::type> &>(__t.__base_)73      .get();74}75template <class... _Tp> constexpr tuple<_Tp...> make_tuple(_Tp... __t) {76  return tuple<_Tp...>(__t...);77}78constexpr int __char_traits_length_checked(const char *__s) {79  return __builtin_strlen(__s);80}81struct basic_string_view {82  constexpr basic_string_view() {}83  constexpr basic_string_view(const char *__s)84      : __data_(__s), __size_(__char_traits_length_checked(__s)) {}85  constexpr const char *begin() { return __data_; }86  constexpr const char *end() {87    return __data_ + __size_;88  }89  const char *__data_;90  int __size_;91};92template <class _Algorithm>93constexpr pair<const char *, char *>94__copy_move_unwrap_iters(const char *__first, const char *__last,95                         char *__out_first) {96  pair<const char *, const char *> __range = {__first, __last};97  auto __result = _Algorithm()(__range.first, __range.second, __out_first);98  return make_pair(__result.first, __result.second);99}100struct __copy_impl {101  constexpr pair<const char *, char *>102  operator()(const char *__first, const char *__last, char *__result) {103    const int __n(__last - __first);104    __constexpr_memmove(__result, __first, __element_count(__n));105    return make_pair(__last, __result);106  }107};108constexpr char *copy(const char *__first, const char *__last, char *__result) {109  return __copy_move_unwrap_iters<__copy_impl>(__first, __last, __result).second;110}111constexpr char *copy_n(const char *__first, int __orig_n, char *__result) {112  return copy(__first, __first + __orig_n, __result);113}114template <int _Size> struct array {115  basic_string_view __elems_[_Size];116  constexpr basic_string_view &operator[](int __n) { return __elems_[__n]; }117  constexpr basic_string_view operator[](int __n) const {118    return __elems_[__n];119  }120};121 122template <typename> struct FieldId;123 124template <FieldId field> constexpr auto FieldIdToInnerValue() {125  return field.template ToInnerValue<field>();126}127struct FieldNameEnum {128  enum class type;129};130template <int N> using FieldName = FieldNameEnum::type;131template <typename, auto> struct GetParentMessageAtIndexImpl;132template <typename, auto> struct FieldInfoHelper;133template <FieldId...> struct PathImpl;134template <int N> struct LongPathLiteral {135  consteval LongPathLiteral(const char (&s)[N]) {136    copy_n(s, N, long_path)[N] = field_count = long_path_size = 1;137  }138  consteval basic_string_view to_string_view() const { return long_path; }139  char long_path[N + 1];140  int long_path_size;141  int field_count;142};143template <LongPathLiteral kLongPath> consteval auto get_field_components() {144  basic_string_view long_path(kLongPath.to_string_view());145  array<kLongPath.field_count> ret;146  for (int i = 0; i < kLongPath.field_count; ++i)147    ret[i] = long_path;148  return ret;149}150template <LongPathLiteral kLongPath>151constexpr auto kFieldComponents = get_field_components<kLongPath>();152template <LongPathLiteral kLongPath> struct LongPathHelper {153  template <int... I>154  static PathImpl<kFieldComponents<kLongPath>[I]...>155      PathForLongPath(index_sequence<I...>);156  using type =157      decltype(PathForLongPath(make_index_sequence<kLongPath.field_count>{}));158};159template <typename T> struct PathFieldId {160  template <typename Arg> constexpr PathFieldId(Arg &arg) : value(arg) {}161  T value;162};163template <PathFieldId...> constexpr auto PathImplHelper();164 165template <int N> using FieldName = FieldName<N>;166enum class FieldNumber;167template <PathFieldId... fields>168constexpr auto Path = PathImplHelper<fields...>();169template <typename Proto, FieldId field>170using FieldInfo =171    FieldInfoHelper<Proto, FieldIdToInnerValue<field>()>::type;172template <> struct FieldId<FieldNameEnum::type> {173  constexpr FieldId(basic_string_view);174  int size;175  long hash;176  template <auto field> static constexpr auto ToInnerValue() {177    return static_cast<FieldNameEnum::type>(field.hash);178  }179};180FieldId(basic_string_view) -> FieldId<FieldNameEnum::type>;181template <typename Proto, FieldId field, int index>182using GetParentMessageAtIndex = GetParentMessageAtIndexImpl<183    Proto, FieldIdToInnerValue<field>()>::type;184 185template <typename T>186PathFieldId(T &t) -> PathFieldId<decltype(LongPathLiteral(t))>;187template <FieldId... fields1, FieldId... fields2>188constexpr PathImpl<fields1..., fields2...> *ConcatPath(PathImpl<fields1...> *,189                                                       PathImpl<fields2...> *) {190  return nullptr;191}192template <LongPathLiteral long_path_literal>193constexpr LongPathHelper<long_path_literal>::type *SinglePath() {194  return nullptr;195}196template <PathFieldId... fields> constexpr auto PathImplHelper() {197  return ConcatPath(SinglePath<fields.value>()...);198}199template <auto hash_prime, auto offset_bias>200constexpr auto Fnv1a(basic_string_view str) {201  auto hash = offset_bias;202  for (char c : str) {203    hash ^= c;204    hash *= hash_prime;205  }206  return hash;207}208constexpr auto HashField(basic_string_view str) {209  return Fnv1a<1099511628211u, 1039346656037>(str);210}211template <typename FI> struct FieldInfoValueTypeAlias : FI {};212template <typename Proto, auto field> struct FieldInfoHelperBase {213  static constexpr auto MaskFieldNameHash() {214    using FieldEnum = decltype(field);215    return FieldEnum{static_cast<underlying_type_t<FieldEnum>>(field) & 31};216  }217  using internal_type =218      Proto::template FieldInfoImpl<decltype(field), MaskFieldNameHash()>;219};220template <typename Proto, auto field> struct FieldInfoHelper {221  using type = FieldInfoValueTypeAlias<222      typename FieldInfoHelperBase<Proto, field>::internal_type>;223};224 225template <auto... fields>226struct FieldId<const PathImpl<fields...> *> {227  constexpr FieldId(PathImpl<fields...> *) : path() {}228  template <auto field> static constexpr auto ToInnerValue() {229    return field.path;230  }231  const PathImpl<fields...> *path;232};233template <auto... fields>234FieldId(PathImpl<fields...> *)235    -> FieldId<const PathImpl<fields...> *>;236 237template <auto> struct UnpackedField {238  static constexpr bool is_path = false;239};240template <auto... fields, const PathImpl<fields...> *path>241struct UnpackedField<path> {242  static constexpr auto value = make_tuple(fields...);243  static constexpr bool is_path = true;244};245template <typename Proto, FieldId... fields, const PathImpl<fields...> *path>246struct GetParentMessageAtIndexImpl<Proto, path> {247  using type = Proto;248};249 250constexpr FieldId<FieldNameEnum::type>::FieldId(basic_string_view str)251    : size(), hash(HashField(str)) {}252template <FieldId field> constexpr bool IsPath() {253  return UnpackedField<254      FieldIdToInnerValue<field>()>::is_path;255}256template <FieldId field> constexpr auto UnpackFieldToTuple() {257  return UnpackedField<FieldIdToInnerValue<field>()>::value;258}259template <int> struct CompileTimeString {260  consteval CompileTimeString(basic_string_view &v) : internal_view_(v) {}261  basic_string_view &internal_view_;262};263CompileTimeString(basic_string_view) -> CompileTimeString<0>;264 265template <CompileTimeString... parts> struct NameJoiner {266  template <CompileTimeString... after>267  NameJoiner<parts...> operator+(NameJoiner<after...>);268};269template <FieldId> struct FieldNameBuilder;270template <FieldId field>271  requires(!IsPath<field>())272struct FieldNameBuilder<field> {273  template <typename Proto> static auto Get() {274    return NameJoiner<FieldInfo<Proto, field>::name>();275  }276};277template <FieldId field>278  requires(IsPath<field>())279struct FieldNameBuilder<field> {280  static constexpr auto kTuple = UnpackFieldToTuple<field>();281  static constexpr int kTupleSize = tuple_size_v<decltype(kTuple)>;282  template <typename Proto, int... Is> static void Get(index_sequence<Is...>) {283    (FieldNameBuilder<get<Is>(284         kTuple)>::template Get<GetParentMessageAtIndex<Proto, field, Is>>() +285     ...);286  }287  template <typename Proto> static void Get() {288    Get<Proto>(make_index_sequence<kTupleSize>());289  }290};291 292struct T {293  template <typename FieldType, FieldType> struct FieldInfoImpl;294};295void AddPathsToFieldMask() {296  FieldNameBuilder<Path<"message_field", "int32_field">>::Get<T>();297}298template <> struct T::FieldInfoImpl<FieldNumber, FieldNumber{1}> {299  static basic_string_view name;300};301template <>302struct T::FieldInfoImpl<FieldName<1>, FieldName<1>{12}>303    : FieldInfoImpl<FieldNumber, FieldNumber{1}> {};304template <> struct T::FieldInfoImpl<FieldNumber, FieldNumber{10}> {305  static basic_string_view name;306};307template <>308struct T::FieldInfoImpl<FieldName<3>, FieldName<3>{11}>309    : FieldInfoImpl<FieldNumber, FieldNumber{10}> {};310