Skip to content

Commit 994c073

Browse files
committed
Fix as<std::string> based on JohelEGP feedback
While fixing the code I made some clean ups.
1 parent 978d198 commit 994c073

10 files changed

+68
-60
lines changed

include/cpp2util.h

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,9 @@ concept not_bigger_than = std::integral<X> && sizeof(X) <= sizeof(C);
351351
template <typename T>
352352
concept arithmetic = std::is_arithmetic_v<T>;
353353

354-
template <typename T>
355-
concept non_void = !std::same_as<T,void>;
356354

357-
template <typename T>
358-
concept non_string = !std::same_as<T, std::string>;
355+
template <typename X, typename... Ts>
356+
concept non = (!std::same_as<X, Ts> && ...) ;
359357

360358
//-----------------------------------------------------------------------
361359
//
@@ -928,13 +926,13 @@ inline auto to_string(std::same_as<std::any> auto const&) -> std::string
928926
return "std::any";
929927
}
930928

931-
inline auto to_string(bool b) -> std::string
929+
inline auto to_string(std::same_as<bool> auto b) -> std::string
932930
{
933931
return b ? "true" : "false";
934932
}
935933

936-
template<typename T>
937-
inline auto to_string(T&& t) -> std::string
934+
template<non<bool> T>
935+
inline auto to_string(T const& t) -> std::string
938936
requires requires { std::to_string(t); }
939937
{
940938
return std::to_string(t);
@@ -945,22 +943,32 @@ inline auto to_string(char const& t) -> std::string
945943
return std::string{t};
946944
}
947945

948-
inline auto to_string(char const* s) -> std::string
946+
template <std::same_as<char const*> X>
947+
inline auto to_string(X const& s) -> std::string
948+
{
949+
return std::string{s};
950+
}
951+
952+
template <std::same_as<char*> X>
953+
inline auto to_string(X const& s) -> std::string
949954
{
950955
return std::string{s};
951956
}
952957

953-
inline auto to_string(std::string const& s) -> std::string const&
958+
inline auto to_string(std::same_as<std::string_view> auto const& s) -> std::string
959+
{
960+
return std::string{s};
961+
}
962+
963+
inline auto to_string(std::same_as<std::string> auto const& s) -> std::string
954964
{
955965
return s;
956966
}
957967

958-
template<typename T>
959-
inline auto to_string(T const& sv) -> std::string
960-
requires (std::is_convertible_v<T, std::string_view>
961-
&& !std::is_convertible_v<T, const char*>)
968+
template<std::size_t N>
969+
inline auto to_string(const char (&x)[N]) -> std::string
962970
{
963-
return std::string{sv};
971+
return std::string{x};
964972
}
965973

966974
template <typename... Ts>
@@ -1037,25 +1045,24 @@ inline auto to_string(auto&& value, std::string_view) -> std::string
10371045
template <typename T>
10381046
concept has_to_string_overload = requires{ static_cast<std::string (*)(T const&)>(&to_string); };
10391047

1040-
template< std::same_as<std::string> C, non_string X>
1048+
template< std::same_as<std::string> C, non<std::any,std::string> X>
10411049
requires has_to_string_overload<X>
1042-
auto as( X&& x) -> C
1043-
{
1044-
return cpp2::to_string(CPP2_FORWARD(x));
1045-
}
1046-
1047-
template< std::same_as<std::string> C>
1048-
auto as(bool x) -> C
1050+
auto as( X const& x) -> C
10491051
{
10501052
return cpp2::to_string(x);
10511053
}
10521054

10531055
template< std::same_as<std::string> C, std::size_t N>
1054-
auto as(const char (&x)[N]) -> C
1056+
auto as(const char (&x)[N]) -> std::string
10551057
{
10561058
return cpp2::to_string(x);
10571059
}
10581060

1061+
template< std::same_as<std::string> C, std::same_as<bool> X>
1062+
auto as(X const x) -> std::string
1063+
{
1064+
return cpp2::to_string<bool>(x);
1065+
}
10591066

10601067
//-----------------------------------------------------------------------
10611068
//
@@ -1111,14 +1118,12 @@ constexpr auto is( T const& ) -> std::false_type {
11111118
template <template <typename> class C, typename X>
11121119
requires std::derived_from<C<std::remove_reference_t<X>>, std::true_type>
11131120
auto is(X&&) -> std::true_type {
1114-
std::cout << __PRETTY_FUNCTION__ << " " << __LINE__ << std::endl;
11151121
return {};
11161122
}
11171123
11181124
template <template <typename> class C, typename X>
11191125
requires std::derived_from<C<std::remove_reference_t<X>>, std::false_type>
11201126
auto is(X&&) -> std::false_type {
1121-
std::cout << __PRETTY_FUNCTION__ << " " << __LINE__ << std::endl;
11221127
return {};
11231128
}
11241129
*/
@@ -1291,7 +1296,7 @@ inline constexpr auto as() -> auto
12911296
// and trying to cast from a value that is in the half of the value space that isn't
12921297
// representable in the target type C is flagged as a Type safety contract violation
12931298
template< std::integral C, std::integral X >
1294-
requires (not_bigger_than<X, C> && different_sign_types<C, X> && not_valid_convertible_to<X, C>)
1299+
requires (not_bigger_than<X, C> && different_sign_types<C, X> && not_valid_convertible_to<X, C>) && non<X, bool>
12951300
inline constexpr auto as(X const& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> auto
12961301
{
12971302
const C c = static_cast<C>(x);
@@ -1303,12 +1308,18 @@ inline constexpr auto as(X const& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) ->
13031308
}
13041309

13051310
template< typename C, std::same_as<C> X>
1306-
constexpr auto as( X&& x ) -> decltype(auto)
1311+
constexpr auto as( X const& x ) -> decltype(auto)
13071312
{
1308-
return std::forward<X>(x);
1313+
return x;
13091314
}
13101315

1311-
template< typename C, typename X >
1316+
template< typename C, std::same_as<C> X>
1317+
constexpr auto as( X & x ) -> decltype(auto)
1318+
{
1319+
return x;
1320+
}
1321+
1322+
template< non<std::string> C, non<C> X >
13121323
requires valid_convertible_to<X, C>
13131324
|| valid_convertible_to<X, typename C::value_type>
13141325
constexpr auto as( X const& x ) -> auto
@@ -1462,8 +1473,8 @@ inline constexpr auto is( std::any const& x, auto const& value ) -> bool
14621473

14631474
// as
14641475
//
1465-
template<typename T>
1466-
constexpr auto as( std::any const& x ) -> T
1476+
template<typename T, std::same_as<std::any> X>
1477+
constexpr auto as( X const& x ) -> T
14671478
{ return std::any_cast<T>( x ); }
14681479

14691480

@@ -1473,13 +1484,13 @@ constexpr auto as( std::any const& x ) -> T
14731484

14741485
// is Type
14751486
//
1476-
template<non_void T, std::same_as<std::optional<T>> X> // same_as needed for clang
1487+
template<non<void> T, std::same_as<std::optional<T>> X> // same_as needed for clang
14771488
constexpr auto is( X const& x ) -> bool
14781489
{ return x.has_value(); }
14791490

14801491
// handled by pointer_like overload is it good?
14811492
//
1482-
// template<std::same_as<empty> T, non_void U>
1493+
// template<std::same_as<empty> T, non<void> U>
14831494
// constexpr auto is( std::optional<U> const& x ) -> bool
14841495
// { return !x.has_value(); }
14851496

regression-tests/mixed-overview-of-as-casts.cpp2

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ main: () = {
120120
a : std::any = 12;
121121
print("( a{12} as int ) is (12)", ( a as int ) is (12), true);
122122
print("( a{12} as std::string )", expect_throws(:() = a$ as std::string;), "throws");
123-
print("std::any(12) as std::string", std::any(12) as std::string, "std::any");
124123
}
125124

126125
{// optional

regression-tests/test-results/apple-clang-14/mixed-overview-of-as-casts.cpp.execution

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
| ( as_const(v){monostate} as std::monostate ) is cpp2::empty| true| true| OK|what is expected behaviour? |
4444
| ( a{12} as int ) is (12)| true| true| OK| |
4545
| ( a{12} as std::string )| throws| throws| OK| |
46-
| std::any(12) as std::string|std::any|std::any| OK| |
4746
| ( o{42} as int ) is (42)| true| true| OK| |
4847
| ( o{42} as long ) is (42l)| true| true| OK| |
4948
| ( o{42} as std::tuple<long> ) is (std::tuple<long>(42))| true| true| OK| |

regression-tests/test-results/apple-clang-14/pure2-as-cast-arithetic-types-bigger-to-smaller.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-arithetic-types-bigger-to-smaller.cpp:7:
2-
../../../include/cpp2util.h:1803:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<unsigned char, unsigned short &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
2+
../../../include/cpp2util.h:1837:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<unsigned char, unsigned short &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
33
static_assert(
44
^
55
pure2-as-cast-arithetic-types-bigger-to-smaller.cpp:19:19: note: in instantiation of function template specialization 'cpp2::as_<unsigned char, unsigned short>' requested here

regression-tests/test-results/apple-clang-14/pure2-as-cast-bigger-signed-to-smaller-unsigned.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-bigger-signed-to-smaller-unsigned.cpp:7:
2-
../../../include/cpp2util.h:1803:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<unsigned char, short &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
2+
../../../include/cpp2util.h:1837:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<unsigned char, short &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
33
static_assert(
44
^
55
pure2-as-cast-bigger-signed-to-smaller-unsigned.cpp:19:19: note: in instantiation of function template specialization 'cpp2::as_<unsigned char, short>' requested here

regression-tests/test-results/apple-clang-14/pure2-as-cast-class-to-unrelated-class.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-class-to-unrelated-class.cpp:7:
2-
../../../include/cpp2util.h:1809:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<A, B &&>' "No safe 'as' cast available - please check your cast"
2+
../../../include/cpp2util.h:1843:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<A, B &&>' "No safe 'as' cast available - please check your cast"
33
static_assert(
44
^
55
pure2-as-cast-class-to-unrelated-class.cpp2:12:19: note: in instantiation of function template specialization 'cpp2::as_<A, B>' requested here

regression-tests/test-results/apple-clang-14/pure2-as-cast-custom-class-to-string.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-custom-class-to-string.cpp:7:
2-
../../../include/cpp2util.h:1809:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<std::string, A &&>' "No safe 'as' cast available - please check your cast"
2+
../../../include/cpp2util.h:1843:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<std::string, A &&>' "No safe 'as' cast available - please check your cast"
33
static_assert(
44
^
55
pure2-as-cast-custom-class-to-string.cpp2:11:19: note: in instantiation of function template specialization 'cpp2::as_<std::string, A>' requested here

regression-tests/test-results/apple-clang-14/pure2-as-cast-double-to-int.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-double-to-int.cpp:7:
2-
../../../include/cpp2util.h:1803:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<int, double &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
2+
../../../include/cpp2util.h:1837:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<int, double &&>' "'as' does not allow unsafe narrowing conversions - if you're sure you want this, use `unsafe_narrow<T>()` to force the conversion"
33
static_assert(
44
^
55
pure2-as-cast-double-to-int.cpp:19:19: note: in instantiation of function template specialization 'cpp2::as_<int, double>' requested here

regression-tests/test-results/apple-clang-14/pure2-as-cast-to-unrelated-type.cpp.output

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
In file included from pure2-as-cast-to-unrelated-type.cpp:7:
2-
../../../include/cpp2util.h:1809:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<A, int &>' "No safe 'as' cast available - please check your cast"
2+
../../../include/cpp2util.h:1843:9: error: static_assert failed due to requirement 'program_violates_type_safety_guarantee<A, int &>' "No safe 'as' cast available - please check your cast"
33
static_assert(
44
^
55
pure2-as-cast-to-unrelated-type.cpp2:5:19: note: in instantiation of function template specialization 'cpp2::as_<A, int &>' requested here

regression-tests/test-results/mixed-overview-of-as-casts.cpp

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
#include "cpp2util.h"
77

88

9-
#line 143 "mixed-overview-of-as-casts.cpp2"
9+
#line 142 "mixed-overview-of-as-casts.cpp2"
1010
class A;
1111
class B;
1212
class C;
1313

1414

15-
#line 149 "mixed-overview-of-as-casts.cpp2"
15+
#line 148 "mixed-overview-of-as-casts.cpp2"
1616
template<int I> class VA;
1717

1818
class VC;
1919

2020

21-
#line 156 "mixed-overview-of-as-casts.cpp2"
21+
#line 155 "mixed-overview-of-as-casts.cpp2"
2222
class VD;
2323

2424

@@ -50,28 +50,28 @@ struct ThrowingConstruction {
5050
auto main() -> int;
5151

5252

53-
#line 143 "mixed-overview-of-as-casts.cpp2"
53+
#line 142 "mixed-overview-of-as-casts.cpp2"
5454
class A {
5555
public: A() = default;
5656
public: A(A const&) = delete; /* No 'that' constructor, suppress copy */
5757
public: auto operator=(A const&) -> void = delete;
5858

59-
#line 143 "mixed-overview-of-as-casts.cpp2"
59+
#line 142 "mixed-overview-of-as-casts.cpp2"
6060
};
6161
class B {
6262
public: B() = default;
6363
public: B(B const&) = delete; /* No 'that' constructor, suppress copy */
6464
public: auto operator=(B const&) -> void = delete;
6565

66-
#line 144 "mixed-overview-of-as-casts.cpp2"
66+
#line 143 "mixed-overview-of-as-casts.cpp2"
6767
};
6868
class C: public A {
6969
public: C() = default;
7070
public: C(C const&) = delete; /* No 'that' constructor, suppress copy */
7171
public: auto operator=(C const&) -> void = delete;
7272

7373

74-
#line 147 "mixed-overview-of-as-casts.cpp2"
74+
#line 146 "mixed-overview-of-as-casts.cpp2"
7575
};
7676

7777
template<int I> class VA {
@@ -81,7 +81,7 @@ public: virtual ~VA() noexcept;
8181
public: VA(VA const&) = delete; /* No 'that' constructor, suppress copy */
8282
public: auto operator=(VA const&) -> void = delete;
8383

84-
#line 149 "mixed-overview-of-as-casts.cpp2"
84+
#line 148 "mixed-overview-of-as-casts.cpp2"
8585
};
8686

8787
class VC: public VA<0>, public VA<1> {
@@ -90,7 +90,7 @@ class VC: public VA<0>, public VA<1> {
9090
public: auto operator=(VC const&) -> void = delete;
9191

9292

93-
#line 154 "mixed-overview-of-as-casts.cpp2"
93+
#line 153 "mixed-overview-of-as-casts.cpp2"
9494
};
9595

9696
class VD: public VA<2> {
@@ -99,38 +99,38 @@ class VD: public VA<2> {
9999
public: auto operator=(VD const&) -> void = delete;
100100

101101

102-
#line 158 "mixed-overview-of-as-casts.cpp2"
102+
#line 157 "mixed-overview-of-as-casts.cpp2"
103103
};
104104

105105
[[nodiscard]] auto pred_i(cpp2::in<int> x) -> bool;
106106

107107

108-
#line 164 "mixed-overview-of-as-casts.cpp2"
108+
#line 163 "mixed-overview-of-as-casts.cpp2"
109109
[[nodiscard]] auto pred_d(cpp2::in<double> x) -> bool;
110110

111111

112-
#line 168 "mixed-overview-of-as-casts.cpp2"
112+
#line 167 "mixed-overview-of-as-casts.cpp2"
113113
[[nodiscard]] auto pred_(auto const& x) -> bool;
114114

115115

116-
#line 172 "mixed-overview-of-as-casts.cpp2"
116+
#line 171 "mixed-overview-of-as-casts.cpp2"
117117
extern std::array<int,5> col;
118118

119119
auto print(auto const& what, auto const& value, auto const& expected, auto const& comment) -> void;
120120

121121

122-
#line 185 "mixed-overview-of-as-casts.cpp2"
122+
#line 184 "mixed-overview-of-as-casts.cpp2"
123123
auto print(auto const& what, auto const& value, auto const& expected) -> void;
124124

125125

126-
#line 189 "mixed-overview-of-as-casts.cpp2"
126+
#line 188 "mixed-overview-of-as-casts.cpp2"
127127
auto print(auto const& what, auto const& value, auto const& expected, auto const& result, auto const& comment) -> void;
128128

129129

130-
#line 198 "mixed-overview-of-as-casts.cpp2"
130+
#line 197 "mixed-overview-of-as-casts.cpp2"
131131
auto print_header() -> void;
132132

133-
#line 207 "mixed-overview-of-as-casts.cpp2"
133+
#line 206 "mixed-overview-of-as-casts.cpp2"
134134

135135
#include <iomanip>
136136

@@ -244,7 +244,6 @@ auto main() -> int{
244244
std::any a {12};
245245
print("( a{12} as int ) is (12)", cpp2::is((cpp2::as_<int>(a)), (12)), true);
246246
print("( a{12} as std::string )", expect_throws([_0 = std::move(a)]() -> void { cpp2::as_<std::string>(_0); }), "throws");
247-
print("std::any(12) as std::string", cpp2::as_<std::string>(std::any(12)), "std::any");
248247
}
249248

250249
{// optional
@@ -266,7 +265,7 @@ auto main() -> int{
266265

267266
template <int I> VA<I>::~VA() noexcept{}
268267

269-
#line 160 "mixed-overview-of-as-casts.cpp2"
268+
#line 159 "mixed-overview-of-as-casts.cpp2"
270269
[[nodiscard]] auto pred_i(cpp2::in<int> x) -> bool{
271270
return cpp2::cmp_greater(x,0);
272271
}

0 commit comments

Comments
 (0)