Skip to content

Commit a5c3dc3

Browse files
committed
Add interpolation support for more std types, closes #37, closes #39, closes #40
1 parent c4ea291 commit a5c3dc3

File tree

3 files changed

+102
-2
lines changed

3 files changed

+102
-2
lines changed

include/cpp2util.h

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -763,14 +763,58 @@ inline auto to_string(std::string const& s) -> std::string const&
763763
return s;
764764
}
765765

766+
template<typename T>
767+
inline auto to_string(T const& sv) -> std::string
768+
requires (std::is_convertible_v<T, std::string_view>
769+
&& !std::is_convertible_v<T, const char*>)
770+
{
771+
return std::string{sv};
772+
}
773+
766774
template<typename T>
767775
inline auto to_string(std::optional<T> const& o) -> std::string {
768776
if (o.has_value()) {
769-
return std::to_string(o.value());
777+
return cpp2::to_string(o.value());
770778
}
771779
return "(empty)";
772780
}
773781

782+
template <typename... Ts>
783+
inline auto to_string(std::variant<Ts...> const& v) -> std::string
784+
{
785+
if (v.valueless_by_exception()) return "(empty)";
786+
// Need to guard this with is_any otherwise the get_if is illegal
787+
if constexpr (is_any<std::monostate, Ts...>) if (std::get_if<std::monostate>(&v) != nullptr) return "(empty)";
788+
789+
return std::visit([](auto&& arg) -> std::string {
790+
if constexpr (requires { cpp2::to_string(arg); }) {
791+
return cpp2::to_string(arg);
792+
}
793+
return "";
794+
}, v);
795+
}
796+
797+
template < typename T, typename U>
798+
inline auto to_string(std::pair<T,U> const& p) -> std::string
799+
{
800+
return "(" + cpp2::to_string(p.first) + ", " + cpp2::to_string(p.second) + ")";
801+
}
802+
803+
template < typename... Ts>
804+
inline auto to_string(std::tuple<Ts...> const& t) -> std::string
805+
{
806+
if constexpr (sizeof...(Ts) == 0) {
807+
return "()";
808+
} else {
809+
std::string out = "(" + cpp2::to_string(std::get<0>(t));
810+
std::apply([&out](auto&&, auto&&... args) {
811+
((out += ", " + cpp2::to_string(args)), ...);
812+
}, t);
813+
out += ")";
814+
return out;
815+
}
816+
}
817+
774818
inline auto to_string(...) -> std::string {
775819
return "(customize me - no cpp2::to_string overload exists for this type)";
776820
}

regression-tests/mixed-string-interpolation.cpp2

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
#include <iostream>
2+
#include <string_view>
3+
#include <utility>
4+
#include <tuple>
25

36
main: () -> int = {
47
a := 2;
@@ -7,4 +10,29 @@ main: () -> int = {
710

811
b = 42;
912
std::cout << "a^2 + b = (a * a + b.value())$\n";
13+
14+
sv: std::string_view = "my string_view";
15+
std::cout << "sv = (sv)$\n";
16+
17+
osv: std::optional<std::string_view> = ();
18+
std::cout << "osv = (osv)$\n";
19+
osv = "string literal bound to optional string_view";
20+
std::cout << "osv = (osv)$\n";
21+
22+
var: std::variant<std::monostate, std::string, double> = ();
23+
std::cout << "var = (var)$\n";
24+
var = "abracadabra";
25+
std::cout << "var = (var)$\n";
26+
var = 2.71828;
27+
std::cout << "var = (var)$\n";
28+
29+
mypair: std::pair<int, double> = (12, 3.4);
30+
std::cout << "mypair = (mypair)$\n";
31+
32+
tup1: std::tuple<int> = (12);
33+
tup2: std::tuple<int, double> = (12, 3.4);
34+
tup3: std::tuple<int, double, std::string> = (12, 3.4, "456");
35+
std::cout << "tup1 = (tup1)$\n";
36+
std::cout << "tup2 = (tup2)$\n";
37+
std::cout << "tup3 = (tup3)$\n";
1038
}

regression-tests/test-results/mixed-string-interpolation.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33

44
#line 1 "mixed-string-interpolation.cpp2"
55
#include <iostream>
6+
#include <string_view>
7+
#include <utility>
8+
#include <tuple>
69

710
[[nodiscard]] auto main() -> int;
811

912
//=== Cpp2 definitions ==========================================================
1013

11-
#line 2 "mixed-string-interpolation.cpp2"
14+
#line 5 "mixed-string-interpolation.cpp2"
1215

1316
[[nodiscard]] auto main() -> int{
1417
auto a { 2 };
@@ -17,4 +20,29 @@
1720

1821
b = 42;
1922
std::cout << "a^2 + b = " + cpp2::to_string(a * a + b.value()) + "\n";
23+
24+
std::string_view sv { "my string_view" };
25+
std::cout << "sv = " + cpp2::to_string(sv) + "\n";
26+
27+
std::optional<std::string_view> osv { };
28+
std::cout << "osv = " + cpp2::to_string(osv) + "\n";
29+
osv = "string literal bound to optional string_view";
30+
std::cout << "osv = " + cpp2::to_string(osv) + "\n";
31+
32+
std::variant<std::monostate,std::string,double> var { };
33+
std::cout << "var = " + cpp2::to_string(var) + "\n";
34+
var = "abracadabra";
35+
std::cout << "var = " + cpp2::to_string(var) + "\n";
36+
var = 2.71828;
37+
std::cout << "var = " + cpp2::to_string(var) + "\n";
38+
39+
std::pair<int,double> mypair { 12, 3.4 };
40+
std::cout << "mypair = " + cpp2::to_string(mypair) + "\n";
41+
42+
std::tuple<int> tup1 { 12 };
43+
std::tuple<int,double> tup2 { 12, 3.4 };
44+
std::tuple<int,double,std::string> tup3 { 12, 3.4, "456" };
45+
std::cout << "tup1 = " + cpp2::to_string(tup1) + "\n";
46+
std::cout << "tup2 = " + cpp2::to_string(tup2) + "\n";
47+
std::cout << "tup3 = " + cpp2::to_string(tup3) + "\n";
2048
}

0 commit comments

Comments
 (0)