Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
StdCompat.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#include <mutex>
7#include <shared_mutex>
8
9#include "StdCompat.h"
10
11using namespace Stroika::Foundation;
12using namespace Stroika::Foundation::Common::StdCompat;
13
14/*
15 ********************************************************************************
16 ******************** Checks on the 'named requirement' concepts ****************
17 ********************************************************************************
18 *
19 * Each concept in StdCompat.h documents which standard types it must, and must not, accept. Those are
20 * asserted here rather than in the header so that the <mutex>/<shared_mutex> needed to name the types
21 * costs ONE translation unit, rather than every one that includes StdCompat.h - which is most of Stroika.
22 *
23 * The NEGATIVE cases are the ones with teeth. A concept that accepts everything constrains nothing, and
24 * that failure is invisible until someone instantiates the constrained template with the wrong type.
25 */
26
27namespace {
28 // Every std lockable type offers lock ()/unlock ()/try_lock () together, so nothing in the standard
29 // library separates BasicLockable from Lockable. This does.
30 struct OnlyBasicLockable_ {
31 void lock ();
32 void unlock ();
33 };
34 // ... and this separates Lockable from TimedLockable without relying on std::mutex staying as it is.
35 struct LockableButNotTimed_ {
36 void lock ();
37 void unlock ();
38 bool try_lock ();
39 };
40}
41
42// The types each concept must accept
43static_assert (BasicLockable<mutex> and BasicLockable<recursive_mutex> and BasicLockable<timed_mutex> and BasicLockable<shared_mutex> and
44 BasicLockable<unique_lock<mutex>>);
45static_assert (Lockable<mutex> and Lockable<recursive_mutex> and Lockable<timed_mutex> and Lockable<shared_mutex>);
46static_assert (TimedLockable<timed_mutex> and TimedLockable<recursive_timed_mutex>);
47static_assert (TimedMutex<timed_mutex> and TimedMutex<recursive_timed_mutex>);
48
49// ... and that each is STRICTLY STRONGER than the one it refines. Nothing in the standard library can
50// check this - every std lockable type offers lock ()/unlock ()/try_lock ()/try_lock_for ()/try_lock_until ()
51// as a set - so it takes purpose-built types. Without these, a concept that had collapsed into its base
52// would still pass every assertion above.
53static_assert (BasicLockable<OnlyBasicLockable_> and not Lockable<OnlyBasicLockable_>);
54static_assert (Lockable<LockableButNotTimed_> and not TimedLockable<LockableButNotTimed_>);
55
56// ... and that they are not vacuously true, which a botched requires-clause silently would be
57static_assert (not BasicLockable<int> and not TimedMutex<int>);