@@ -228,12 +228,18 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
228228
229229 using ParentType::getTrailingObjectsImpl;
230230
231- // This function contains only a static_assert BaseTy is final. The
232- // static_assert must be in a function, and not at class-level
233- // because BaseTy isn't complete at class instantiation time, but
234- // will be by the time this function is instantiated.
235- static void verifyTrailingObjectsAssertions () {
231+ template <bool Strict> static void verifyTrailingObjectsAssertions () {
232+ // The static_assert for BaseTy must be in a function, and not at
233+ // class-level because BaseTy isn't complete at class instantiation time,
234+ // but will be by the time this function is instantiated.
236235 static_assert (std::is_final<BaseTy>(), " BaseTy must be final." );
236+
237+ // Verify that templated getTrailingObjects() is used only with multiple
238+ // trailing types. Use getTrailingObjectsNonStrict() which does not check
239+ // this.
240+ static_assert (!Strict || sizeof ...(TrailingTys) > 1 ,
241+ " Use templated getTrailingObjects() only when there are "
242+ " multiple trailing types" );
237243 }
238244
239245 // These two methods are the base of the recursion for this method.
@@ -283,7 +289,7 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
283289 // / (which must be one of those specified in the class template). The
284290 // / array may have zero or more elements in it.
285291 template <typename T> const T *getTrailingObjects () const {
286- verifyTrailingObjectsAssertions ();
292+ verifyTrailingObjectsAssertions< true > ();
287293 // Forwards to an impl function with overloads, since member
288294 // function templates can't be specialized.
289295 return this ->getTrailingObjectsImpl (
@@ -295,7 +301,7 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
295301 // / (which must be one of those specified in the class template). The
296302 // / array may have zero or more elements in it.
297303 template <typename T> T *getTrailingObjects () {
298- verifyTrailingObjectsAssertions ();
304+ verifyTrailingObjectsAssertions< true > ();
299305 // Forwards to an impl function with overloads, since member
300306 // function templates can't be specialized.
301307 return this ->getTrailingObjectsImpl (
@@ -310,14 +316,20 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
310316 static_assert (sizeof ...(TrailingTys) == 1 ,
311317 " Can use non-templated getTrailingObjects() only when there "
312318 " is a single trailing type" );
313- return getTrailingObjects<FirstTrailingType>();
319+ verifyTrailingObjectsAssertions<false >();
320+ return this ->getTrailingObjectsImpl (
321+ static_cast <const BaseTy *>(this ),
322+ TrailingObjectsBase::OverloadToken<FirstTrailingType>());
314323 }
315324
316325 FirstTrailingType *getTrailingObjects () {
317326 static_assert (sizeof ...(TrailingTys) == 1 ,
318327 " Can use non-templated getTrailingObjects() only when there "
319328 " is a single trailing type" );
320- return getTrailingObjects<FirstTrailingType>();
329+ verifyTrailingObjectsAssertions<false >();
330+ return this ->getTrailingObjectsImpl (
331+ static_cast <BaseTy *>(this ),
332+ TrailingObjectsBase::OverloadToken<FirstTrailingType>());
321333 }
322334
323335 // Functions that return the trailing objects as ArrayRefs.
@@ -337,6 +349,31 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
337349 return ArrayRef (getTrailingObjects (), N);
338350 }
339351
352+ // Non-strict forms of templated `getTrailingObjects` that work with single
353+ // trailing type.
354+ template <typename T> const T *getTrailingObjectsNonStrict () const {
355+ verifyTrailingObjectsAssertions<false >();
356+ return this ->getTrailingObjectsImpl (
357+ static_cast <const BaseTy *>(this ),
358+ TrailingObjectsBase::OverloadToken<T>());
359+ }
360+
361+ template <typename T> T *getTrailingObjectsNonStrict () {
362+ verifyTrailingObjectsAssertions<false >();
363+ return this ->getTrailingObjectsImpl (
364+ static_cast <BaseTy *>(this ), TrailingObjectsBase::OverloadToken<T>());
365+ }
366+
367+ template <typename T>
368+ MutableArrayRef<T> getTrailingObjectsNonStrict (size_t N) {
369+ return MutableArrayRef (getTrailingObjectsNonStrict<T>(), N);
370+ }
371+
372+ template <typename T>
373+ ArrayRef<T> getTrailingObjectsNonStrict (size_t N) const {
374+ return ArrayRef (getTrailingObjectsNonStrict<T>(), N);
375+ }
376+
340377 // / Returns the size of the trailing data, if an object were
341378 // / allocated with the given counts (The counts are in the same order
342379 // / as the template arguments). This does not include the size of the
0 commit comments