-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconcepts.cpp
More file actions
110 lines (91 loc) · 2.86 KB
/
concepts.cpp
File metadata and controls
110 lines (91 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* @file concepts.cpp
* @brief
* @author Haoming Bai <haomingbai@hotmail.com>
* @date 2025-07-06
*
* Copyright © 2025 Haoming Bai
* SPDX-License-Identifier: MIT
*
* @details
*/
#ifndef CONCEPTS_CPP
#define CONCEPTS_CPP
#include <concepts>
#include <cstddef>
#include <iterator>
#include <type_traits>
template <typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template <typename T>
concept Subtractable = requires(T a, T b) {
{ a - b } -> std::convertible_to<T>;
};
template <typename T>
concept Multiplyable = requires(T a, T b) {
{ a * b } -> std::convertible_to<T>;
};
template <typename T>
concept Dividable = requires(T a, T b) {
{ a / b } -> std::convertible_to<T>;
};
template <typename Container, typename E>
concept RandomAccessContainer =
requires(const Container &c, std::size_t index) {
// 要求有size()成员函数,返回类型可转换为size_t
{ c.size() } -> std::convertible_to<std::size_t>;
// 要求支持随机访问(下标操作符)
{ c[index] } -> std::convertible_to<E>;
};
template <typename T1, typename T2>
concept AddableWith = requires(T1 a, T2 b) {
{ a + b } -> std::convertible_to<std::common_type_t<T1, T2>>;
};
template <typename T1, typename T2>
concept SubtractableWith = requires(T1 a, T2 b) {
{ a - b } -> std::convertible_to<std::common_type_t<T1, T2>>;
};
template <typename T1, typename T2>
concept MultiplyableWith = requires(T1 a, T2 b) {
{ a * b } -> std::convertible_to<std::common_type_t<T1, T2>>;
};
template <typename T1, typename T2>
concept DividableWith = requires(T1 a, T2 b) {
{ a / b } -> std::convertible_to<std::common_type_t<T1, T2>>;
};
template <typename T>
concept Accumulateable = requires(T a, size_t b) {
{ a * b } -> std::convertible_to<T>;
};
template <typename T>
concept Partable = requires(T a, size_t b) {
{ a / b } -> std::convertible_to<T>;
};
template <typename T>
concept Negativable = requires(T a) {
{ -a } -> std::convertible_to<T>;
};
template <typename Container, typename E>
concept RandomStdContainer =
RandomAccessContainer<Container, E> && requires(Container arr) {
{ arr.begin() };
{ arr.end() } -> std::same_as<decltype(arr.begin())>;
{ std::next(arr.begin()) } -> std::same_as<decltype(arr.begin())>;
{ std::prev(arr.end()) } -> std::same_as<decltype(arr.begin())>;
{ arr.begin() < arr.end() } -> std::convertible_to<bool>;
{ arr.empty() } -> std::convertible_to<bool>;
};
template <typename T>
concept FullyComparable = requires(T a, T b) {
{ a < b } -> std::convertible_to<bool>;
{ a == b } -> std::convertible_to<bool>;
{ a > b } -> std::convertible_to<bool>;
};
template <typename Container, typename E>
concept RandomResizableContainer =
RandomStdContainer<Container, E> && requires(Container arr, size_t x) {
{ arr.resize(x) };
};
#endif