@@ -228,12 +228,18 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
228
228
229
229
using ParentType::getTrailingObjectsImpl;
230
230
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.
236
235
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" );
237
243
}
238
244
239
245
// These two methods are the base of the recursion for this method.
@@ -283,7 +289,7 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
283
289
// / (which must be one of those specified in the class template). The
284
290
// / array may have zero or more elements in it.
285
291
template <typename T> const T *getTrailingObjects () const {
286
- verifyTrailingObjectsAssertions ();
292
+ verifyTrailingObjectsAssertions< true > ();
287
293
// Forwards to an impl function with overloads, since member
288
294
// function templates can't be specialized.
289
295
return this ->getTrailingObjectsImpl (
@@ -295,7 +301,7 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
295
301
// / (which must be one of those specified in the class template). The
296
302
// / array may have zero or more elements in it.
297
303
template <typename T> T *getTrailingObjects () {
298
- verifyTrailingObjectsAssertions ();
304
+ verifyTrailingObjectsAssertions< true > ();
299
305
// Forwards to an impl function with overloads, since member
300
306
// function templates can't be specialized.
301
307
return this ->getTrailingObjectsImpl (
@@ -310,14 +316,20 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
310
316
static_assert (sizeof ...(TrailingTys) == 1 ,
311
317
" Can use non-templated getTrailingObjects() only when there "
312
318
" 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>());
314
323
}
315
324
316
325
FirstTrailingType *getTrailingObjects () {
317
326
static_assert (sizeof ...(TrailingTys) == 1 ,
318
327
" Can use non-templated getTrailingObjects() only when there "
319
328
" 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>());
321
333
}
322
334
323
335
// Functions that return the trailing objects as ArrayRefs.
@@ -337,6 +349,31 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
337
349
return ArrayRef (getTrailingObjects (), N);
338
350
}
339
351
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
+
340
377
// / Returns the size of the trailing data, if an object were
341
378
// / allocated with the given counts (The counts are in the same order
342
379
// / as the template arguments). This does not include the size of the
0 commit comments