brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · f953fa4 Raw
158 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// UNSUPPORTED: no-threads10// UNSUPPORTED: c++03, c++11, c++1411 12// <mutex>13 14// template <class ...Mutex> class scoped_lock;15 16// explicit scoped_lock(mutex_type& m);17 18#include <mutex>19#include <cassert>20#include "test_macros.h"21 22struct TestMutex {23    bool locked = false;24    TestMutex() = default;25    ~TestMutex() { assert(!locked); }26 27    void lock() { assert(!locked); locked = true; }28    bool try_lock() { if (locked) return false; locked = true; return true; }29    void unlock() { assert(locked); locked = false; }30 31    TestMutex(TestMutex const&) = delete;32    TestMutex& operator=(TestMutex const&) = delete;33};34 35#if !defined(TEST_HAS_NO_EXCEPTIONS)36struct TestMutexThrows {37    bool locked = false;38    bool throws_on_lock = false;39 40    TestMutexThrows() = default;41    ~TestMutexThrows() { assert(!locked); }42 43    void lock() {44        assert(!locked);45        if (throws_on_lock) {46            throw 42;47        }48        locked = true;49    }50 51    bool try_lock() {52        if (locked) return false;53        lock();54        return true;55    }56 57    void unlock() { assert(locked); locked = false; }58 59    TestMutexThrows(TestMutexThrows const&) = delete;60    TestMutexThrows& operator=(TestMutexThrows const&) = delete;61};62#endif // !defined(TEST_HAS_NO_EXCEPTIONS)63 64int main(int, char**)65{66    {67        using LG = std::scoped_lock<>;68        LG lg;69        (void)lg;70    }71    {72        using LG = std::scoped_lock<TestMutex>;73        TestMutex m1;74        {75            LG lg(m1);76            assert(m1.locked);77        }78        assert(!m1.locked);79    }80    {81        using LG = std::scoped_lock<TestMutex, TestMutex>;82        TestMutex m1, m2;83        {84            LG lg(m1, m2);85            assert(m1.locked && m2.locked);86        }87        assert(!m1.locked && !m2.locked);88    }89    {90        using LG = std::scoped_lock<TestMutex, TestMutex, TestMutex>;91        TestMutex m1, m2, m3;92        {93            LG lg(m1, m2, m3);94            assert(m1.locked && m2.locked && m3.locked);95        }96        assert(!m1.locked && !m2.locked && !m3.locked);97    }98#if !defined(TEST_HAS_NO_EXCEPTIONS)99    {100        using MT = TestMutexThrows;101        using LG = std::scoped_lock<MT>;102        MT m1;103        m1.throws_on_lock = true;104        try {105            LG lg(m1);106            assert(false);107        } catch (int) {}108        assert(!m1.locked);109    }110    {111        using MT = TestMutexThrows;112        using LG = std::scoped_lock<MT, MT>;113        MT m1, m2;114        m1.throws_on_lock = true;115        try {116            LG lg(m1, m2);117            assert(false);118        } catch (int) {}119        assert(!m1.locked && !m2.locked);120    }121    {122        using MT = TestMutexThrows;123        using LG = std::scoped_lock<MT, MT, MT>;124        MT m1, m2, m3;125        m2.throws_on_lock = true;126        try {127            LG lg(m1, m2, m3);128            assert(false);129        } catch (int) {}130        assert(!m1.locked && !m2.locked && !m3.locked);131    }132#endif133 134#if TEST_STD_VER >= 17135    {136    TestMutex m1, m2, m3;137        {138        std::scoped_lock sl{};139        static_assert((std::is_same<decltype(sl), std::scoped_lock<>>::value), "" );140        }141        {142        std::scoped_lock sl{m1};143        static_assert((std::is_same<decltype(sl), std::scoped_lock<decltype(m1)>>::value), "" );144        }145        {146        std::scoped_lock sl{m1, m2};147        static_assert((std::is_same<decltype(sl), std::scoped_lock<decltype(m1), decltype(m2)>>::value), "" );148        }149        {150        std::scoped_lock sl{m1, m2, m3};151        static_assert((std::is_same<decltype(sl), std::scoped_lock<decltype(m1), decltype(m2), decltype(m3)>>::value), "" );152        }153    }154#endif155 156  return 0;157}158