AUI Framework  master
Cross-platform module-based framework for developing C++20 desktop applications
concepts.h
1/*
2 * AUI Framework - Declarative UI toolkit for modern C++20
3 * Copyright (C) 2020-2024 Alex2772 and Contributors
4 *
5 * SPDX-License-Identifier: MPL-2.0
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 */
11
12#pragma once
13
14#include <concepts>
15#include <utility>
16#include <functional>
17#include <type_traits>
18#include "callables.h"
19
20namespace aui {
21
22 // the following concepts are partially copying stl functionality but android has no support for these
23 template <class Derived, class Base>
24 concept derived_from = std::is_base_of_v<Base, Derived> &&
25 std::is_convertible_v<const volatile Derived*, const volatile Base*>;
26
35 template<typename F, typename... Args>
36 concept invocable = requires(F&& f, Args&&... args) {
37 { std::invoke(f, std::forward<Args>(args)...) };
38 };
39
40 template <class From, class To>
41 concept convertible_to = std::is_convertible_v<From, To> && requires {
42 static_cast<To>(std::declval<From>());
43 };
44
45 template < class T >
46 concept destructible = std::is_nothrow_destructible_v<T>;
47
48 template < class T, class... Args >
49 concept constructible_from = destructible<T> && std::is_constructible_v<T, Args...>;
50
51 template<typename _Tp>
52 concept move_constructible = constructible_from<_Tp, _Tp> && convertible_to<_Tp, _Tp>;
53
54 template< class T >
55 concept copy_constructible = move_constructible<T> &&
56 constructible_from<T, T&> &&
57 convertible_to<T&, T> &&
58 constructible_from<T, const T&> &&
59 convertible_to<const T&, T> &&
60 constructible_from<T, const T> &&
61 convertible_to<const T, T>;
62
63 namespace detail {
64 template< class T, class U >
65 concept SameHelper = std::is_same_v<T, U>;
66 }
67
68 template< class T, class U >
69 concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
70
71
72
73 template < class T, class U >
74 concept common_reference_with = same_as<std::remove_reference_t<T>, std::remove_reference_t<T>> &&
75 convertible_to<T, std::remove_reference_t<U>> &&
76 convertible_to<U, std::remove_reference_t<T>>;
77
78 template< class LHS, class RHS >
79 concept assignable_from = std::is_lvalue_reference_v<LHS> &&
80 common_reference_with<const std::remove_reference_t<LHS>&,
81 const std::remove_reference_t<RHS>&> &&
82 requires(LHS lhs, RHS&& rhs) {
83 { lhs = std::forward<RHS>(rhs) } -> std::same_as<LHS>;
84 };
85 template< class T >
86 concept swappable =
87 requires(T& a, T& b) {
88 std::swap(a, b);
89 };
90
91
92 template < class T >
93 concept movable = std::is_object_v<T> &&
94 move_constructible<T> &&
95 assignable_from<T&, T> &&
96 swappable<T>;
97
98 template <class T>
99 concept copyable = copy_constructible<T> &&
100 movable<T> &&
101 assignable_from<T&, T&> &&
102 assignable_from<T&, const T&> &&
103 assignable_from<T&, const T>;
104
105 template<class T>
106 concept default_initializable = constructible_from<T> &&
107 requires { T{}; } &&
108 requires { ::new T; };
109
110
111 template <class T>
112 concept semiregular = copyable<T> && default_initializable<T>;
113
114 template <class T>
115 concept regular = semiregular<T>;
116
117 template<class I>
118 concept incrementable = regular<I> && requires(I i) {
119 { i++ } -> std::same_as<I>;
120 };
121
122
123 template<typename F, typename... Args>
124 concept predicate = requires(F&& f, Args&&... args) {
125 { f(std::forward<Args>(args)...) } -> same_as<bool>;
126 };
127
128 // aui concepts
129
130 template<typename F, typename From, typename To>
131 concept mapper = requires(F&& f, From&& from) {
132 { std::invoke(f, std::forward<From>(from)) } -> aui::convertible_to<To>;
133 };
134
135 template<typename F, typename ProducedObject>
136 concept factory = requires(F&& f) {
137 { std::invoke(f) } -> aui::convertible_to<ProducedObject>;
138 };
139
143 template<typename T>
144 concept arithmetic = std::is_arithmetic_v<T>;
145
146 template<typename T>
147 concept unsigned_integral = std::is_unsigned_v<T>;
148}
Concept shortcut to std::is_arithmetic_v.
Definition: concepts.h:144
Invokable concept.
Definition: concepts.h:36
API_AUI_CORE const ACommandLineArgs & args() noexcept
Definition: OSAndroid.cpp:29