201
201
#include < type_traits>
202
202
#include < new>
203
203
#include < memory>
204
+ #include < tuple>
204
205
#include < string>
205
206
#include < string_view>
206
207
#include < vector>
216
217
#include < compare>
217
218
#include < iterator>
218
219
#include < concepts>
220
+ #include < system_error>
219
221
220
222
#ifndef CPP2_NO_EXCEPTIONS
221
223
#include < exception>
@@ -324,8 +326,8 @@ class contract_group {
324
326
using handler = void (*)(CPP2_MESSAGE_PARAM msg CPP2_SOURCE_LOCATION_PARAM);
325
327
326
328
constexpr contract_group (handler h = {}) : reporter(h) { }
327
- constexpr auto set_handler (handler h) -> handler ;
328
- constexpr auto get_handler () const -> handler { return reporter; }
329
+ constexpr auto set_handler (handler h);
330
+ constexpr auto get_handler () const -> handler { return reporter; }
329
331
constexpr auto expects (bool b, CPP2_MESSAGE_PARAM msg = " " CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT)
330
332
-> void { if (!b) reporter (msg CPP2_SOURCE_LOCATION_ARG); }
331
333
private:
@@ -373,11 +375,9 @@ auto inline Testing = contract_group(
373
375
}
374
376
);
375
377
376
- constexpr auto contract_group::set_handler (handler h) -> handler {
378
+ constexpr auto contract_group::set_handler (handler h) {
377
379
Default.expects (h);
378
- auto old = reporter;
379
380
reporter = h;
380
- return old;
381
381
}
382
382
383
383
@@ -681,19 +681,37 @@ class out {
681
681
//
682
682
// -----------------------------------------------------------------------
683
683
//
684
- #ifdef _MSC_VER
684
+ #if defined( _MSC_VER) && !defined(__clang_major__)
685
685
#define CPP2_FORCE_INLINE __forceinline
686
686
#define CPP2_FORCE_INLINE_LAMBDA [[msvc::forceinline]]
687
+ #define CPP2_LAMBDA_NO_DISCARD
687
688
#else
688
689
#define CPP2_FORCE_INLINE __attribute__ ((always_inline))
689
690
#define CPP2_FORCE_INLINE_LAMBDA __attribute__ ((always_inline))
691
+
692
+ #if defined (__clang_major__)
693
+ // Also check __cplusplus, only to satisfy Clang -pedantic-errors
694
+ #if __cplusplus >= 202302L && (__clang_major__ > 13 || (__clang_major__ == 13 && __clang_minor__ >= 2 ))
695
+ #define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
696
+ #else
697
+ #define CPP2_LAMBDA_NO_DISCARD
698
+ #endif
699
+ #elif defined(__GNUC__)
700
+ #if __GNUC__ >= 9
701
+ #define CPP2_LAMBDA_NO_DISCARD [[nodiscard]]
702
+ #else
703
+ #define CPP2_LAMBDA_NO_DISCARD
704
+ #endif
705
+ #else
706
+ #define CPP2_LAMBDA_NO_DISCARD
707
+ #endif
690
708
#endif
691
709
692
710
693
711
// Note: [&] is because a nested UFCS might be viewed as trying to capture 'this'
694
712
695
713
#define CPP2_UFCS (FUNCNAME,PARAM1,...) \
696
- [&](auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
714
+ [&] CPP2_LAMBDA_NO_DISCARD (auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
697
715
if constexpr (requires{ CPP2_FORWARD (obj).FUNCNAME (CPP2_FORWARD (params)...); }) { \
698
716
return CPP2_FORWARD (obj).FUNCNAME (CPP2_FORWARD (params)...); \
699
717
} else { \
@@ -702,7 +720,7 @@ class out {
702
720
}(PARAM1, __VA_ARGS__)
703
721
704
722
#define CPP2_UFCS_0 (FUNCNAME,PARAM1 ) \
705
- [&](auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
723
+ [&] CPP2_LAMBDA_NO_DISCARD (auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
706
724
if constexpr (requires{ CPP2_FORWARD (obj).FUNCNAME (); }) { \
707
725
return CPP2_FORWARD (obj).FUNCNAME (); \
708
726
} else { \
@@ -713,7 +731,7 @@ class out {
713
731
#define CPP2_UFCS_REMPARENS (...) __VA_ARGS__
714
732
715
733
#define CPP2_UFCS_TEMPLATE (FUNCNAME,TEMPARGS,PARAM1,...) \
716
- [&](auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
734
+ [&] CPP2_LAMBDA_NO_DISCARD (auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
717
735
if constexpr (requires{ CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD (params)...); }) { \
718
736
return CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD (params)...); \
719
737
} else { \
@@ -722,7 +740,7 @@ class out {
722
740
}(PARAM1, __VA_ARGS__)
723
741
724
742
#define CPP2_UFCS_TEMPLATE_0 (FUNCNAME,TEMPARGS,PARAM1 ) \
725
- [&](auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
743
+ [&] CPP2_LAMBDA_NO_DISCARD (auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
726
744
if constexpr (requires{ CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
727
745
return CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
728
746
} else { \
@@ -734,7 +752,7 @@ class out {
734
752
// But for non-local lambdas [&] is not allowed
735
753
736
754
#define CPP2_UFCS_NONLOCAL (FUNCNAME,PARAM1,...) \
737
- [](auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
755
+ [] CPP2_LAMBDA_NO_DISCARD (auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
738
756
if constexpr (requires{ CPP2_FORWARD (obj).FUNCNAME (CPP2_FORWARD (params)...); }) { \
739
757
return CPP2_FORWARD (obj).FUNCNAME (CPP2_FORWARD (params)...); \
740
758
} else { \
@@ -743,7 +761,7 @@ class out {
743
761
}(PARAM1, __VA_ARGS__)
744
762
745
763
#define CPP2_UFCS_0_NONLOCAL (FUNCNAME,PARAM1 ) \
746
- [](auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
764
+ [] CPP2_LAMBDA_NO_DISCARD (auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
747
765
if constexpr (requires{ CPP2_FORWARD (obj).FUNCNAME (); }) { \
748
766
return CPP2_FORWARD (obj).FUNCNAME (); \
749
767
} else { \
@@ -752,7 +770,7 @@ class out {
752
770
}(PARAM1)
753
771
754
772
#define CPP2_UFCS_TEMPLATE_NONLOCAL (FUNCNAME,TEMPARGS,PARAM1,...) \
755
- [](auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
773
+ [] CPP2_LAMBDA_NO_DISCARD (auto && obj, auto && ...params) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
756
774
if constexpr (requires{ CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD (params)...); }) { \
757
775
return CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (CPP2_FORWARD (params)...); \
758
776
} else { \
@@ -761,7 +779,7 @@ class out {
761
779
}(PARAM1, __VA_ARGS__)
762
780
763
781
#define CPP2_UFCS_TEMPLATE_0_NONLOCAL (FUNCNAME,TEMPARGS,PARAM1 ) \
764
- [](auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
782
+ [] CPP2_LAMBDA_NO_DISCARD (auto && obj) CPP2_FORCE_INLINE_LAMBDA -> decltype (auto ) { \
765
783
if constexpr (requires{ CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); }) { \
766
784
return CPP2_FORWARD (obj).template FUNCNAME CPP2_UFCS_REMPARENS TEMPARGS (); \
767
785
} else { \
@@ -1334,82 +1352,67 @@ constexpr auto as( X const& x ) -> decltype(auto)
1334
1352
1335
1353
// -----------------------------------------------------------------------
1336
1354
//
1337
- // A variation of GSL's final_action_success and finally to run only on success
1338
- // (based on a PR I contributed to Microsoft GSL)
1355
+ // A variation of GSL's final_action_success / finally
1339
1356
//
1340
- // final_action_success ensures something is run at the end of a scope
1341
- // if no exception is thrown
1357
+ // finally ensures something is run at the end of a scope always
1342
1358
//
1343
- // finally_success is a convenience function to make a final_action_success_success
1359
+ // finally_success ensures something is run at the end of a scope
1360
+ // if no exception is thrown
1344
1361
//
1345
1362
// -----------------------------------------------------------------------
1346
1363
//
1347
1364
1348
1365
template <class F >
1349
- class final_action_success
1366
+ class finally_success
1350
1367
{
1351
1368
public:
1352
- explicit final_action_success (const F& ff) noexcept : f{ff} { }
1353
- explicit final_action_success (F&& ff) noexcept : f{std::move (ff)} { }
1369
+ explicit finally_success (const F& ff) noexcept : f{ff} { }
1370
+ explicit finally_success (F&& ff) noexcept : f{std::move (ff)} { }
1354
1371
1355
- ~final_action_success () noexcept
1372
+ ~finally_success () noexcept
1356
1373
{
1357
1374
if (invoke && ecount == std::uncaught_exceptions ()) {
1358
1375
f ();
1359
1376
}
1360
1377
}
1361
1378
1362
- final_action_success (final_action_success && that) noexcept
1379
+ finally_success (finally_success && that) noexcept
1363
1380
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false ))
1364
1381
{ }
1365
1382
1366
- final_action_success (final_action_success const &) = delete ;
1367
- void operator = (final_action_success const &) = delete ;
1368
- void operator = (final_action_success &&) = delete ;
1383
+ finally_success (finally_success const &) = delete ;
1384
+ void operator = (finally_success const &) = delete ;
1385
+ void operator = (finally_success &&) = delete ;
1369
1386
1370
1387
private:
1371
1388
F f;
1372
1389
int ecount = std::uncaught_exceptions();
1373
1390
bool invoke = true ;
1374
1391
};
1375
1392
1376
- [[nodiscard]] auto finally_success (auto && f) noexcept
1377
- {
1378
- return final_action_success<CPP2_TYPEOF (f)>{CPP2_FORWARD (f)};
1379
- }
1380
-
1381
-
1382
- //
1383
- // Same, but clean up also on exceptional paths
1384
- //
1385
1393
1386
1394
template <class F >
1387
- class final_action
1395
+ class finally
1388
1396
{
1389
1397
public:
1390
- explicit final_action (const F& ff) noexcept : f{ff} { }
1391
- explicit final_action (F&& ff) noexcept : f{std::move (ff)} { }
1398
+ explicit finally (const F& ff) noexcept : f{ff} { }
1399
+ explicit finally (F&& ff) noexcept : f{std::move (ff)} { }
1392
1400
1393
- ~final_action () noexcept { f (); }
1401
+ ~finally () noexcept { f (); }
1394
1402
1395
- final_action (final_action && that) noexcept
1403
+ finally (finally && that) noexcept
1396
1404
: f(std::move(that.f)), invoke(std::exchange(that.invoke, false ))
1397
1405
{ }
1398
1406
1399
- final_action (final_action const &) = delete ;
1400
- void operator =(final_action const &) = delete ;
1401
- void operator =(final_action &&) = delete ;
1407
+ finally (finally const &) = delete ;
1408
+ void operator =(finally const &) = delete ;
1409
+ void operator =(finally &&) = delete ;
1402
1410
1403
1411
private:
1404
1412
F f;
1405
1413
bool invoke = true ;
1406
1414
};
1407
1415
1408
- [[nodiscard]] auto finally (auto && f) noexcept
1409
- {
1410
- return final_action<CPP2_TYPEOF (f)>{CPP2_FORWARD (f)};
1411
- }
1412
-
1413
1416
1414
1417
// -----------------------------------------------------------------------
1415
1418
//
0 commit comments