Skip to content

Commit 0e28c00

Browse files
committed
fix: check constructability, preserve copy- and moveability
1 parent 3063848 commit 0e28c00

6 files changed

Lines changed: 72 additions & 54 deletions

File tree

.github/workflows/test.yml

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
11
on:
22
workflow_dispatch:
33
push:
4-
branches: [master]
5-
4+
branches: ["**"]
65
paths-ignore:
76
- "**/*.md"
8-
- "**/*.yml"
9-
10-
pull_request:
11-
branches: [master]
127

138
name: 🧪 Run Tests
14-
159
jobs:
1610
test:
1711
strategy:
1812
fail-fast: false
1913

2014
matrix:
2115
config: [Release, Debug]
22-
type: [gcc, clang, msvc]
16+
type: [gcc, clang, msvc, clang-cl, apple-clang]
2317

2418
include:
2519
- type: gcc
20+
os: ubuntu-latest
2621
container: archlinux:base-devel
2722
deps: pacman --noconfirm -Syu git cmake gcc ninja make
2823

2924
- type: clang
25+
os: ubuntu-latest
3026
container: archlinux:base-devel
3127
deps: pacman --noconfirm -Syu git cmake clang ninja make
3228

33-
runs-on: ${{ contains(matrix.type, 'msvc') && 'windows-latest' || 'ubuntu-latest' }}
29+
- type: msvc
30+
os: windows-latest
31+
32+
- type: clang-cl
33+
os: windows-latest
34+
cmake_args: -T ClangCL -A x64
35+
36+
- type: apple-clang
37+
os: macos-15
38+
xcode: 16.3
39+
40+
runs-on: ${{ matrix.os }}
3441
container: ${{ matrix.container }}
3542

36-
name: "${{ matrix.type }} (⚙️: ${{ matrix.config }})"
43+
name: ${{ matrix.type }}-${{ matrix.config }}
3744

3845
steps:
3946
- name: 📦 Checkout
@@ -42,9 +49,15 @@ jobs:
4249
- name: 🧰 Dependencies
4350
run: ${{ matrix.deps }}
4451

52+
- name: 🍏 Setup XCode
53+
uses: maxim-lobanov/setup-xcode@v1
54+
if: ${{ matrix.type == 'apple-clang' }}
55+
with:
56+
xcode-version: ${{ matrix.xcode }}
57+
4558
- name: 🔧 Compile
4659
run: |
47-
cmake -B build -Dlockpp_tests=ON ${{ matrix.cmake_args }}
60+
cmake -B build -Dereignis_tests=ON ${{ matrix.cmake_args }}
4861
cmake --build build --config ${{ matrix.config }}
4962
5063
- name: 🔬 Run Tests

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cmake_minimum_required(VERSION 3.16)
2-
project(lockpp LANGUAGES CXX VERSION 3.1)
2+
project(lockpp LANGUAGES CXX VERSION 3.2.0)
33

44
# --------------------------------------------------------------------------------------------------------
55
# Library options

cmake/cpm.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
#
33
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
44

5-
set(CPM_DOWNLOAD_VERSION 0.40.1)
6-
set(CPM_HASH_SUM "117cbf2711572f113bab262933eb5187b08cfc06dce0714a1ee94f2183ddc3ec")
5+
set(CPM_DOWNLOAD_VERSION 0.40.8)
6+
set(CPM_HASH_SUM "78ba32abdf798bc616bab7c73aac32a17bbd7b06ad9e26a6add69de8f3ae4791")
77

88
if(CPM_SOURCE_CACHE)
99
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")

include/lockpp/lock.hpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
#include "traits.hpp"
44
#include "locked.hpp"
55

6+
#include <memory>
7+
68
namespace lockpp
79
{
8-
template <typename T, typename Mutex = std::shared_mutex>
10+
template <typename T, typename Mutex = std::shared_mutex, template <typename...> typename Wrapper = std::unique_ptr>
911
class lock
1012
{
1113
template <typename>
@@ -16,38 +18,41 @@ namespace lockpp
1618

1719
private:
1820
T m_value;
19-
mutable Mutex m_mutex;
21+
Wrapper<Mutex> m_mutex;
22+
23+
public:
24+
lock() = default;
25+
lock(const lock &) = default;
26+
lock(lock &&) noexcept(std::is_nothrow_move_constructible_v<T>) = default;
2027

2128
public:
2229
template <typename... Ts>
23-
explicit lock(Ts &&...);
30+
requires std::constructible_from<T, Ts...>
31+
lock(Ts &&...);
2432

2533
public:
2634
template <template <typename> class Lock = write_lock, typename... Ts>
2735
[[nodiscard]] locked<T, Lock<Mutex>> write(Ts &&...) &;
2836

2937
public:
30-
template <template <typename> class Lock = read_lock, typename... Ts>
31-
[[nodiscard]] locked<const T, Lock<Mutex>> read(Ts &&...) const &;
32-
33-
template <template <typename> class Lock = read_lock, typename... Ts>
34-
[[nodiscard]] locked<const T, Lock<Mutex>> read(Ts &&...) const && = delete;
38+
template <template <typename> class Lock = read_lock, typename Self, typename... Ts>
39+
requires std::is_lvalue_reference_v<Self>
40+
[[nodiscard]] locked<const T, Lock<Mutex>> read(this Self &&, Ts &&...);
3541

3642
public:
3743
template <typename O>
3844
requires std::assignable_from<T &, O>
39-
void assign(O &&value) &;
45+
void assign(O &&) &;
4046

4147
public:
42-
[[nodiscard]] T &get_unsafe() &;
43-
[[nodiscard]] T &get_unsafe() && = delete;
44-
45-
[[nodiscard]] T &get_unsafe() const &;
46-
[[nodiscard]] T &get_unsafe() const && = delete;
48+
template <typename Self>
49+
requires std::is_lvalue_reference_v<Self>
50+
[[nodiscard]] T &get_unsafe(this Self &&);
4751

4852
public:
49-
[[nodiscard]] T copy() const &;
50-
[[nodiscard]] T copy() const && = delete;
53+
template <typename Self>
54+
requires std::is_lvalue_reference_v<Self> and std::copyable<T>
55+
[[nodiscard]] T copy(this Self &&);
5156
};
5257
} // namespace lockpp
5358

include/lockpp/lock.inl

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,51 @@
44

55
namespace lockpp
66
{
7-
template <typename T, typename Mutex>
7+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
88
template <typename... Ts>
9-
lock<T, Mutex>::lock(Ts &&...args) : m_value(std::forward<Ts>(args)...)
9+
requires std::constructible_from<T, Ts...>
10+
lock<T, Mutex, Wrapper>::lock(Ts &&...args) : m_value(std::forward<Ts>(args)...)
1011
{
1112
}
1213

13-
template <typename T, typename Mutex>
14+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
1415
template <template <typename> class Lock, typename... Ts>
15-
locked<T, Lock<Mutex>> lock<T, Mutex>::write(Ts &&...lock_args) &
16+
locked<T, Lock<Mutex>> lock<T, Mutex, Wrapper>::write(Ts &&...lock_args) &
1617
{
17-
return {&m_value, m_mutex, std::forward<Ts>(lock_args)...};
18+
return {&m_value, *m_mutex, std::forward<Ts>(lock_args)...};
1819
}
1920

20-
template <typename T, typename Mutex>
21-
template <template <typename> class Lock, typename... Ts>
22-
locked<const T, Lock<Mutex>> lock<T, Mutex>::read(Ts &&...lock_args) const &
21+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
22+
template <template <typename> class Lock, typename Self, typename... Ts>
23+
requires std::is_lvalue_reference_v<Self>
24+
locked<const T, Lock<Mutex>> lock<T, Mutex, Wrapper>::read(this Self &&self, Ts &&...lock_args)
2325
{
24-
return {&m_value, m_mutex, std::forward<Ts>(lock_args)...};
26+
return {&self.m_value, *std::forward<Self>(self).m_mutex, std::forward<Ts>(lock_args)...};
2527
}
2628

27-
template <typename T, typename Mutex>
29+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
2830
template <typename O>
2931
requires std::assignable_from<T &, O>
30-
void lock<T, Mutex>::assign(O &&value) &
32+
void lock<T, Mutex, Wrapper>::assign(O &&value) &
3133
{
3234
auto locked = write();
3335
*locked = std::forward<O>(value);
3436
}
3537

36-
template <typename T, typename Mutex>
37-
T &lock<T, Mutex>::get_unsafe() &
38-
{
39-
return m_value;
40-
}
41-
42-
template <typename T, typename Mutex>
43-
T &lock<T, Mutex>::get_unsafe() const &
38+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
39+
template <typename Self>
40+
requires std::is_lvalue_reference_v<Self>
41+
T &lock<T, Mutex, Wrapper>::get_unsafe(this Self &&self)
4442
{
45-
return m_value;
43+
return std::forward<Self>(self).m_value;
4644
}
4745

48-
template <typename T, typename Mutex>
49-
T lock<T, Mutex>::copy() const &
46+
template <typename T, typename Mutex, template <typename...> typename Wrapper>
47+
template <typename Self>
48+
requires std::is_lvalue_reference_v<Self> and std::copyable<T>
49+
T lock<T, Mutex, Wrapper>::copy(this Self &&self)
5050
{
51-
auto locked = read();
51+
auto locked = std::forward<Self>(self).read();
5252
return *locked;
5353
}
5454
} // namespace lockpp

include/lockpp/locked.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace lockpp
55
template <typename T, typename Lock>
66
class locked
77
{
8-
template <typename, typename>
8+
template <typename, typename, template <typename...> typename>
99
friend class lock;
1010

1111
private:

0 commit comments

Comments
 (0)