@@ -1216,7 +1216,7 @@ union alignas(max_align_t) _Move_only_function_data {
1216
1216
char _Data; // For aliasing
1217
1217
1218
1218
template <class _Fn>
1219
- static constexpr size_t _Buf_offset() noexcept {
1219
+ [[nodiscard]] static constexpr size_t _Buf_offset() noexcept {
1220
1220
if constexpr (alignof(_Fn) <= sizeof(_Impl)) {
1221
1221
return sizeof(_Impl); // Data immediately after impl
1222
1222
} else {
@@ -1225,34 +1225,35 @@ union alignas(max_align_t) _Move_only_function_data {
1225
1225
}
1226
1226
1227
1227
template <class _Fn>
1228
- static constexpr size_t _Buf_size() noexcept {
1228
+ [[nodiscard]] static constexpr size_t _Buf_size() noexcept {
1229
1229
return sizeof(_Pointers) - _Buf_offset<_Fn>();
1230
1230
}
1231
1231
1232
1232
template <class _Fn>
1233
- constexpr void* _Buf_ptr() {
1233
+ [[nodiscard]] constexpr void* _Buf_ptr() noexcept {
1234
1234
return &_Data + _Buf_offset<_Fn>();
1235
1235
}
1236
1236
1237
1237
template <class _Fn>
1238
- _Fn* _Small_fn_ptr() {
1238
+ [[nodiscard]] _Fn* _Small_fn_ptr() noexcept {
1239
1239
return static_cast<_Fn*>(_Buf_ptr<_Fn>());
1240
1240
}
1241
1241
1242
1242
template <class _Fn>
1243
- _Fn* _Large_fn_ptr() {
1243
+ [[nodiscard]] _Fn* _Large_fn_ptr() noexcept {
1244
1244
return static_cast<_Fn*>(_Pointers[1]);
1245
1245
}
1246
1246
1247
- void _Set_large_fn_ptr(void* _Value) {
1247
+ void _Set_large_fn_ptr(void* const _Value) noexcept {
1248
1248
_Pointers[1] = _Value;
1249
1249
}
1250
1250
};
1251
1251
1252
1252
template <class _Rx, class... Args>
1253
1253
struct _Move_only_function_impl { // per-callable-type structure acting as a virtual function table
1254
- // using vtable emulations gives more flexibility for optimizations and eliminates the need for RTTI
1255
- // (RTTI saving may be significant as with lambdas and binds there may be a lot of distinct callable types)
1254
+ // using vtable emulations gives more flexibility for optimizations and reduces the need for RTTIs
1255
+ // (RTTI saving may be significant as with lambdas and binds there may be a lot of distinct callable types,
1256
+ // we don't have distinct wrapper class type for each callable type, only distinct functions when needed)
1256
1257
1257
1258
// Calls target
1258
1259
_Rx (*_Invoke)(_Move_only_function_data&, Args...);
@@ -1263,12 +1264,12 @@ struct _Move_only_function_impl { // per-callable-type structure acting as a vir
1263
1264
};
1264
1265
1265
1266
template <class _Rx, class... Args>
1266
- [[noreturn]] _Rx _Function_no_callable(_Move_only_function_data&, Args...) {
1267
+ [[noreturn]] _Rx _Function_no_callable(_Move_only_function_data&, Args...) noexcept {
1267
1268
_CSTD abort(); // We are not std::function to throw bad_function_call
1268
1269
}
1269
1270
1270
- constexpr void _Function_noop_move(_Move_only_function_data&, _Move_only_function_data&) noexcept {}
1271
- constexpr void _Function_noop_destroy(_Move_only_function_data&) noexcept {}
1271
+ inline void _Function_noop_move(_Move_only_function_data&, _Move_only_function_data&) noexcept {}
1272
+ inline void _Function_noop_destroy(_Move_only_function_data&) noexcept {}
1272
1273
1273
1274
template <class _Rx, class... Args>
1274
1275
inline constexpr _Move_only_function_impl<_Rx, Args...> _Null_move_only_function = {
@@ -1278,12 +1279,12 @@ inline constexpr _Move_only_function_impl<_Rx, Args...> _Null_move_only_function
1278
1279
};
1279
1280
1280
1281
template <class _Fn, class _Rx, class... _Types>
1281
- _Rx _Function_invoke_small(_Move_only_function_data& _Self, _Types... _Args) {
1282
+ [[nodiscard]] _Rx _Function_invoke_small(_Move_only_function_data& _Self, _Types... _Args) {
1282
1283
return (*_Self._Small_fn_ptr<_Fn>()) (_STD forward<_Types>(_Args)...);
1283
1284
}
1284
1285
1285
1286
template <class _Fn, class _Rx, class... _Types>
1286
- _Rx _Function_invoke_large(_Move_only_function_data& _Self, _Types... _Args) {
1287
+ [[nodiscard]] _Rx _Function_invoke_large(_Move_only_function_data& _Self, _Types... _Args) {
1287
1288
return (*_Self._Large_fn_ptr<_Fn>()) (_STD forward<_Types>(_Args)...);
1288
1289
}
1289
1290
@@ -1328,7 +1329,7 @@ void _Function_move_memcpy(_Move_only_function_data& _Self, _Move_only_function_
1328
1329
}
1329
1330
1330
1331
template <class _Fn>
1331
- void* _Function_new_large(_Fn&& _Callable) {
1332
+ [[nodiscard]] void* _Function_new_large(_Fn&& _Callable) {
1332
1333
struct [[nodiscard]] _Guard_type {
1333
1334
void* _Ptr;
1334
1335
@@ -1347,7 +1348,7 @@ void* _Function_new_large(_Fn&& _Callable) {
1347
1348
if constexpr (alignof(_Fn) <= __STDCPP_DEFAULT_NEW_ALIGNMENT__) {
1348
1349
_Guard._Ptr = ::operator new(sizeof(_Fn));
1349
1350
} else {
1350
- _Guard._Ptr = ::operator new(sizeof(_Fn), align_val_t{alignof(_Fn)});
1351
+ _Guard._Ptr = ::operator new (sizeof(_Fn), align_val_t{alignof(_Fn)});
1351
1352
}
1352
1353
::new (_Guard._Ptr) _Fn(_STD move(_Callable));
1353
1354
return exchange(_Guard._Ptr, nullptr);
@@ -1384,12 +1385,12 @@ public:
1384
1385
_Get_impl()->_Destroy(_Data);
1385
1386
}
1386
1387
1387
- bool _Is_null() const noexcept {
1388
+ [[nodiscard]] bool _Is_null() const noexcept {
1388
1389
return _Data._Impl == &_Null_move_only_function<_Rx, _Types...>;
1389
1390
}
1390
1391
1391
1392
template <class _Fn>
1392
- static constexpr bool _Large_function_engaged() noexcept {
1393
+ [[nodiscard]] static constexpr bool _Large_function_engaged() noexcept {
1393
1394
return sizeof(_Fn) > _Move_only_function_data::_Buf_size<_Fn>()
1394
1395
|| !is_nothrow_move_constructible_v<_Fn> || alignof(_Fn) > alignof(max_align_t);
1395
1396
}
@@ -1398,12 +1399,12 @@ public:
1398
1399
return size_t{_Size + sizeof(void*) - 1} & ~size_t{sizeof(void*) - 1};
1399
1400
}
1400
1401
1401
- const _Impl_t* _Get_impl() const noexcept {
1402
+ [[nodiscard]] const _Impl_t* _Get_impl() const noexcept {
1402
1403
return static_cast<const _Impl_t*>(_Data._Impl);
1403
1404
}
1404
1405
1405
1406
template <class _Fn>
1406
- static constexpr _Impl_t _Create_impl() noexcept {
1407
+ [[nodiscard]] static constexpr _Impl_t _Create_impl() noexcept {
1407
1408
_Impl_t _Impl{};
1408
1409
if constexpr (_Large_function_engaged<_Fn>()) {
1409
1410
_Impl._Invoke = _Function_invoke_large<_Fn, _Rx, _Types...>;
@@ -1438,7 +1439,7 @@ public:
1438
1439
}
1439
1440
1440
1441
template <class _Fn>
1441
- static const _Impl_t* _Create_impl_ptr() noexcept {
1442
+ [[nodiscard]] static const _Impl_t* _Create_impl_ptr() noexcept {
1442
1443
static constexpr _Impl_t _Impl = _Create_impl<_Fn>();
1443
1444
return &_Impl;
1444
1445
}
@@ -1493,13 +1494,13 @@ public:
1493
1494
this->_Construct_with_fn(_STD forward<_Fn>(_Callable));
1494
1495
}
1495
1496
1496
- explicit operator bool() const noexcept {
1497
+ [[nodiscard]] explicit operator bool() const noexcept {
1497
1498
return !this->_Is_null();
1498
1499
}
1499
1500
1500
1501
using _Call::operator();
1501
1502
1502
- friend bool operator==(const move_only_function& _This, nullptr_t) noexcept {
1503
+ [[nodiscard]] friend bool operator==(const move_only_function& _This, nullptr_t) noexcept {
1503
1504
return _This._Is_null();
1504
1505
}
1505
1506
};
0 commit comments