Skip to content

Commit dca487d

Browse files
committed
Impl
1 parent baf9923 commit dca487d

18 files changed

+374
-74
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ std::cout << map[0] << ' '
2020

2121
// Not dirty-macro-magic! just simple alias.
2222
// SFINAE can be easily made without macro using good-old-school mechanism
23-
template<typename T, preview_requires(preview::integral<T>)>
23+
template<typename T, PREVIEW_REQUIRES(preview::integral<T>)>
2424
void foo(T) {}
2525

2626
// Readable error message!
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//
2+
// Created by yonggyulee on 2024. 10. 20.
3+
//
4+
5+
#ifndef PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_COMMON_REFERENCE_WITH_H_
6+
#define PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_COMMON_REFERENCE_WITH_H_
7+
8+
#include "preview/__concepts_v2/concept_base.h"
9+
#include "preview/__concepts_v2/convertible_to.h"
10+
#include "preview/__concepts_v2/same_as.h"
11+
#include "preview/__type_traits/common_reference.h"
12+
#include "preview/__type_traits/has_typename_type.h"
13+
14+
namespace preview {
15+
16+
#if defined(PREVIEW_USE_LEGACY_CONCEPT)
17+
18+
namespace detail {
19+
20+
template<typename T, typename U>
21+
struct common_reference_with_helper : concepts::concept_base<common_reference_with_helper<T, U>,
22+
has_typename_type<common_reference<T, U>>
23+
> {};
24+
25+
} // namespace detail
26+
27+
template<typename T, typename U>
28+
struct common_reference_with_c : concepts::concept_base<common_reference_with_c<T, U>, decltype(
29+
detail::common_reference_with_helper<T, U>{} && detail::common_reference_with_helper<U, T>{}
30+
)> {};
31+
32+
template<typename T, typename U>
33+
PREVIEW_INLINE_VARIABLE constexpr common_reference_with_c<T, U> common_reference_with;
34+
35+
#else
36+
37+
#endif
38+
39+
} // namespace preview
40+
41+
#endif // PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_COMMON_REFERENCE_WITH_H_

include/preview/__concepts_v2/detail/concept_base.h renamed to include/preview/__concepts_v2/concept_base.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
#define PREVIEW_CONCEPTS_V2_DETAIL_CONCEPT_BASE_H_
77

88
#include "preview/__core/inline_variable.h"
9+
#include "preview/__concepts_v2/detail/config.h"
910
#include "preview/__concepts_v2/detail/constraints_not_satisfied.h"
1011
#include "preview/__concepts_v2/detail/sized_true.h"
1112
#include "preview/__type_traits/bool_constant.h"
1213

1314
namespace preview {
1415
namespace concepts {
1516

17+
using namespace PREVIEW_CONCEPT_LEXICAL_NAMESPACE;
18+
1619
template<bool B> struct valid_tag {};
1720
template<> struct valid_tag<true> { using valid = bool; };
1821

@@ -93,25 +96,25 @@ struct concept_base : Base, valid_tag<Base::value> {
9396
// concept && concept
9497
template<typename C2, typename B2>
9598
friend constexpr auto operator&&(concept_base x, concept_base<C2, B2> y) noexcept {
96-
return conj_c_c(x, y, bool_constant<Base::value>{}, bool_constant<B2::value>{});
99+
return conj_c_c(x, y, preview::bool_constant<Base::value>{}, preview::bool_constant<B2::value>{});
97100
}
98101

99102
// concept && true
100103
template<std::size_t N>
101104
friend constexpr auto operator&&(concept_base, sized_true<N>) noexcept {
102-
return conj_c_t(concept_base{}, sized_true<N>{}, bool_constant<Base::value>{});
105+
return conj_c_t(concept_base{}, sized_true<N>{}, preview::bool_constant<Base::value>{});
103106
}
104107

105108
// true && concept
106109
template<std::size_t N>
107110
friend constexpr auto operator&&(sized_true<N>, concept_base) noexcept {
108-
return conj_t_c(sized_true<N>{}, concept_base{}, bool_constant<Base::value>{});
111+
return conj_t_c(sized_true<N>{}, concept_base{}, preview::bool_constant<Base::value>{});
109112
}
110113

111114
// concept && false
112115
template<typename Error, std::size_t I, std::size_t N, typename... ErrorInfo>
113116
friend constexpr auto operator&&(concept_base, constraints_not_satisfied<Error, at<I, N>, ErrorInfo...> e) noexcept {
114-
return conj_c_f(concept_base{}, e, bool_constant<Base::value>{});
117+
return conj_c_f(concept_base{}, e, preview::bool_constant<Base::value>{});
115118
}
116119

117120
// false && concept
@@ -190,7 +193,7 @@ struct concept_base : Base, valid_tag<Base::value> {
190193

191194

192195
/// negation
193-
friend constexpr auto operator!(concept_base) noexcept { return negation(bool_constant<Base::value>{}); }
196+
friend constexpr auto operator!(concept_base) noexcept { return negation(preview::bool_constant<Base::value>{}); }
194197
};
195198

196199
} // namespace concepts

include/preview/__concepts_v2/constructible_from.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,27 @@
33

44
#include <type_traits>
55

6-
#include "preview/__concepts_v2/detail/concept_base.h"
6+
#include "preview/__concepts_v2/concept_base.h"
77
#include "preview/__concepts_v2/destructible.h"
88

99
namespace preview {
10-
namespace concepts {
10+
11+
#if defined(PREVIEW_USE_LEGACY_CONCEPT)
1112

1213
template<typename T, typename... Args>
13-
struct constructible_from : concept_base<constructible_from<T, Args...>, decltype(
14-
destructible<T>{} && std::is_constructible<T, Args...>{}
14+
struct constructible_from_c : concepts::concept_base<constructible_from_c<T, Args...>, decltype(
15+
destructible<T> && std::is_constructible<T, Args...>{}
1516
)> {};
1617

17-
} // namespace concepts
18+
template<typename T, typename... Args>
19+
PREVIEW_INLINE_VARIABLE constexpr constructible_from_c<T, Args...> constructible_from{};
20+
21+
#else
1822

1923
template<typename T, typename... Args>
20-
PREVIEW_INLINE_VARIABLE constexpr concepts::constructible_from<T, Args...> constructible_from;
24+
concept constructible_from = destructible<T> && std::is_constructible_v<T, Args...>;
25+
26+
#endif
2127

2228
} // namespace preview
2329

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//
2+
// Created by yonggyulee on 2024. 10. 20.
3+
//
4+
5+
#ifndef PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_CONVERTIBLE_TO_H_
6+
#define PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_CONVERTIBLE_TO_H_
7+
8+
#include <type_traits>
9+
10+
#include "preview/__concepts_v2/concept_base.h"
11+
#include "preview/__type_traits/conjunction.h"
12+
#include "preview/__type_traits/is_explicitly_convertible.h"
13+
14+
namespace preview {
15+
16+
#if defined(PREVIEW_USE_LEGACY_CONCEPT)
17+
18+
template<typename From, typename To>
19+
struct convertible_to_c : concepts::concept_base<convertible_to_c<From, To>,
20+
conjunction<
21+
std::is_convertible<From, To>,
22+
is_explicitly_convertible<From, To>
23+
>
24+
>{};
25+
26+
template<typename From, typename To>
27+
PREVIEW_INLINE_VARIABLE convertible_to_c<From, To> convertible_to;
28+
29+
#else
30+
31+
template<typename From, typename To>
32+
concept convertible_to =
33+
std::is_convertible_v<From, To> &&
34+
requires {
35+
static_cast<To>(std::declval<From>());
36+
};
37+
38+
#endif
39+
40+
} // namespace preview
41+
42+
#endif // PREVIEW_INCLUDE_PREVIEW___CONCEPTS_V2_CONVERTIBLE_TO_H_
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Created by yonggyulee on 2024. 10. 20.
3+
//
4+
5+
#ifndef PREVIEW_CONCEPTS_V2_DERIVED_FROM_H_
6+
#define PREVIEW_CONCEPTS_V2_DERIVED_FROM_H_
7+
8+
#include <type_traits>
9+
10+
#include "preview/__concepts_v2/concept_base.h"
11+
#include "preview/__type_traits/conjunction.h"
12+
13+
namespace preview {
14+
15+
#if defined(PREVIEW_USE_LEGACY_CONCEPT)
16+
17+
template<typename Derived, typename Base>
18+
struct derived_from_c : concepts::concept_base<derived_from_c<Derived, Base>,
19+
conjunction<
20+
std::is_base_of<Base, Derived>,
21+
std::is_convertible<const volatile Derived*, const volatile Base*>
22+
>
23+
> {};
24+
25+
template<typename Derived, typename Base>
26+
PREVIEW_INLINE_VARIABLE constexpr derived_from_c<Derived, Base> derived_from;
27+
28+
#else
29+
30+
template<typename Derived, typename Base>
31+
concept derived_from =
32+
std::is_base_of_v<Base, Derived> &&
33+
std::is_convertible_v<const volatile Derived*, const volatile Base*>;
34+
35+
#endif
36+
37+
} // namespace preview
38+
39+
#endif // PREVIEW_CONCEPTS_V2_DERIVED_FROM_H_

include/preview/__concepts_v2/destructible.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
#ifndef PREVIEW_CONCEPTS_V2_DESTRUCTIBLE_H_
22
#define PREVIEW_CONCEPTS_V2_DESTRUCTIBLE_H_
33

4-
#include "preview/__concepts_v2/detail/concept_base.h"
4+
#include <type_traits>
5+
6+
#include "preview/__concepts_v2/concept_base.h"
57

68
namespace preview {
7-
namespace concepts {
89

9-
template<typename T>
10-
struct destructible : concept_base<destructible<T>, std::is_nothrow_destructible<T>> {};
10+
#if defined(PREVIEW_USE_LEGACY_CONCEPT)
1111

12-
} // namespace concepts
12+
template<typename T>
13+
struct destructible_c : concepts::concept_base<destructible_c<T>, std::is_nothrow_destructible<T>> {};
1314

1415
template<typename T>
15-
PREVIEW_INLINE_VARIABLE constexpr concepts::destructible<T> destructible;
16+
PREVIEW_INLINE_VARIABLE constexpr destructible_c<T> destructible;
17+
18+
#else
19+
20+
template<typename T>
21+
concept destructible = std::is_nothrow_destructible_v<T>;
22+
23+
#endif
1624

1725
} // namespace preview
1826

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// Created by yonggyulee on 2024. 10. 20.
3+
//
4+
5+
#ifndef PREVIEW_CONCEPTS_V2_DETAIL_CONFIG_H_
6+
#define PREVIEW_CONCEPTS_V2_DETAIL_CONFIG_H_
7+
8+
#if PREVIEW_CXX_VERSION < 20
9+
#define PREVIEW_USE_LEGACY_CONCEPT
10+
#endif
11+
12+
#define PREVIEW_CONCEPT_LEXICAL_NAMESPACE pc_
13+
#define PREVIEW_CONCEPT_LEXICAL_NAMESPACE_OPEN namespace pc_ {
14+
#define PREVIEW_CONCEPT_LEXICAL_NAMESPACE_CLOSE } // namespace pc_
15+
16+
#endif // PREVIEW_CONCEPTS_V2_DETAIL_CONFIG_H_

include/preview/__concepts_v2/detail/constraints_not_satisfied.h

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
#include <type_traits>
1111

1212
#include "preview/__core/inline_variable.h"
13+
#include "preview/__concepts_v2/detail/config.h"
1314
#include "preview/__concepts_v2/detail/forward_declare.h"
1415
#include "preview/__type_traits/conjunction.h"
1516
#include "preview/__type_traits/is_invocable.h"
1617
#include "preview/__type_traits/is_specialization.h"
1718
#include "preview/__type_traits/negation.h"
1819

19-
namespace preview {
20-
namespace concepts {
20+
// Use shorter namespace to reduce error message length
21+
PREVIEW_CONCEPT_LEXICAL_NAMESPACE_OPEN
2122

2223
template<typename Constraints, typename... Info>
2324
struct constraints_not_satisfied : std::false_type {};
@@ -54,40 +55,41 @@ using concat_error_t = typename concat_error<CNS1, CNS2>::type;
5455
// TODO: Optimize
5556
struct expand_error_fn {
5657
template<typename Constraint, typename... Info>
57-
constexpr auto operator()(constraints_not_satisfied<Constraint, Info...> e) const noexcept {
58-
return call(e, is_invocable<expand_error_fn, Constraint>{});
58+
auto operator()(constraints_not_satisfied<Constraint, Info...> e) const noexcept {
59+
return call(e, preview::is_invocable<expand_error_fn, Constraint>{});
5960
}
6061

6162
// Ignore already expanded error
6263
template<typename Constraint, std::size_t I, std::size_t N, typename... Why, typename... Rest>
63-
constexpr auto operator()(constraints_not_satisfied<Constraint, at<I, N>, because<Why...>, Rest...> e) const noexcept {
64+
auto operator()(constraints_not_satisfied<Constraint, at<I, N>, because<Why...>, Rest...> e) const noexcept {
6465
return e;
6566
}
6667
// This case doesn't exist yest
6768
template<typename Constraint, typename... Why, typename... Rest>
68-
constexpr auto operator()(constraints_not_satisfied<Constraint, because<Why...>, Rest...> e) const noexcept {
69+
auto operator()(constraints_not_satisfied<Constraint, because<Why...>, Rest...> e) const noexcept {
6970
return e;
7071
}
7172

7273
// direct-wrapper of type_traits (e.g., integral = is_integral_v)
73-
template<typename Derived, typename Base, std::enable_if_t<conjunction<
74-
derived_from_bool_constant<Base>,
75-
negation<is_concept<Base>>,
76-
negation<derived_from_template<Base, constraints_not_satisfied>>
74+
template<typename Derived, typename Base, std::enable_if_t<preview::conjunction<
75+
std::is_base_of<std::false_type, Derived>,
76+
preview::concepts::derived_from_bool_constant<Base>,
77+
preview::negation<preview::concepts::is_concept<Base>>,
78+
preview::negation<preview::concepts::derived_from_template<Base, constraints_not_satisfied>>
7779
>::value, int> = 0>
78-
constexpr auto operator()(concept_base<Derived, Base>) const noexcept {
80+
auto operator()(preview::concepts::concept_base<Derived, Base>) const noexcept {
7981
// TODO: Simplify
8082
return constraints_not_satisfied<Derived, at<0, 1>, because<Base, is_false>>{};
8183
}
8284

8385
private:
8486
template<typename Error, typename... Info>
85-
constexpr auto call(constraints_not_satisfied<Error, Info...>, std::true_type) const noexcept {
87+
auto call(constraints_not_satisfied<Error, Info...>, std::true_type) const noexcept {
8688
auto e = (*this)(Error{});
8789
return constraints_not_satisfied<Error, Info..., because<decltype(e)>>{};
8890
}
8991
template<typename Error, typename... Info>
90-
constexpr auto call(constraints_not_satisfied<Error, Info...> e, std::false_type) const noexcept {
92+
auto call(constraints_not_satisfied<Error, Info...> e, std::false_type) const noexcept {
9193
return e;
9294
}
9395
};
@@ -315,7 +317,6 @@ struct constraints_not_satisfied<
315317
and_, C3, at<I3, N3>, because<Why3...>,
316318
Rest... > : std::false_type {};
317319

318-
} // namespace concepts
319-
} // namespace preview
320+
PREVIEW_CONCEPT_LEXICAL_NAMESPACE_CLOSE
320321

321322
#endif // PREVIEW_CONCEPTS_V2_DETAIL_CONSTRAINTS_NOT_SATISFIED_H_

include/preview/__concepts_v2/detail/sized_true.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
#include <cstddef>
99
#include <type_traits>
1010

11-
#include "preview/__concepts_v2/detail/constraints_not_satisfied.h"
11+
#include "preview/__concepts_v2/detail/config.h"
1212

13-
namespace preview {
14-
namespace concepts {
13+
PREVIEW_CONCEPT_LEXICAL_NAMESPACE_OPEN
1514

1615
template<std::size_t N>
1716
struct sized_true : std::true_type {
@@ -55,7 +54,6 @@ struct sized_true : std::true_type {
5554
template<typename E, std::size_t I, std::size_t N, typename...Info>
5655
constexpr sized_true<N> operator!(constraints_not_satisfied<E, at<I, N>, Info...>) noexcept { return {}; }
5756

58-
} // namespace concepts
59-
} // namespace preview
57+
PREVIEW_CONCEPT_LEXICAL_NAMESPACE_CLOSE
6058

6159
#endif // PREVIEW_CONCEPTS_V2_DETAIL_SIZED_TRUE_H_

0 commit comments

Comments
 (0)