Skip to content

Commit 6af78c9

Browse files
committed
Make main(args) zero-allocation
Remove need for `vector` and copying command-line argument strings Now just generate a `string_view` on demand as the caller visits each argument, that is directly bound to the string provided by the host environment
1 parent 510eae8 commit 6af78c9

File tree

5 files changed

+98
-59
lines changed

5 files changed

+98
-59
lines changed

include/cpp2util.h

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,24 +1729,63 @@ class finally_presuccess
17291729

17301730
//-----------------------------------------------------------------------
17311731
//
1732-
// args: see main() arguments as vector<string_view>
1732+
// args: see main() arguments as a container of string_views
1733+
//
1734+
// Does not perform any dynamic memory allocation - each string_view
1735+
// is directly bound to the string provided by the host environment
17331736
//
17341737
//-----------------------------------------------------------------------
17351738
//
1736-
struct args_t : std::vector<std::string_view>
1739+
struct args_t
17371740
{
1738-
args_t(int c, char** v) : vector{static_cast<std::size_t>(c)}, argc{c}, argv{v} {}
1741+
args_t(int c, char** v) : argc{c}, argv{v} {}
1742+
1743+
class iterator {
1744+
public:
1745+
iterator(int c, char** v, int start) : argc{c}, argv{v}, curr{start} {}
1746+
1747+
auto operator*() const {
1748+
if (curr < argc) { return std::string_view{ argv[curr] }; }
1749+
else { return std::string_view{}; }
1750+
}
1751+
1752+
auto operator+(int i) -> iterator {
1753+
if (i > 0) { return { argc, argv, std::min(curr+i, argc) }; }
1754+
else { return { argc, argv, std::max(curr+i, 0 ) }; }
1755+
}
1756+
auto operator-(int i) -> iterator { return operator+(-i); }
1757+
auto operator++() -> iterator& { curr = std::min(curr+1, argc); return *this; }
1758+
auto operator--() -> iterator& { curr = std::max(curr-1, 0 ); return *this; }
1759+
auto operator++(int) -> iterator { auto old = *this; ++*this; return old; }
1760+
auto operator--(int) -> iterator { auto old = *this; ++*this; return old; }
1761+
1762+
auto operator<=>(iterator const&) const = default;
1763+
1764+
private:
1765+
int argc;
1766+
char** argv;
1767+
int curr;
1768+
};
1769+
1770+
auto begin() const -> iterator { return iterator{ argc, argv, 0 }; }
1771+
auto end() const -> iterator { return iterator{ argc, argv, argc }; }
1772+
auto cbegin() const -> iterator { return begin(); }
1773+
auto cend() const -> iterator { return end(); }
1774+
auto size() const -> std::size_t { return argc; }
1775+
auto ssize() const -> int { return argc; }
1776+
1777+
auto operator[](int i) const {
1778+
if (0 <= i && i < argc) { return std::string_view{ argv[i] }; }
1779+
else { return std::string_view{}; }
1780+
}
17391781

17401782
mutable int argc = 0; // mutable for compatibility with frameworks that take 'int& argc'
17411783
char** argv = nullptr;
17421784
};
17431785

17441786
inline auto make_args(int argc, char** argv) -> args_t
17451787
{
1746-
auto ret = args_t{argc, argv};
1747-
auto args = std::span(argv, static_cast<std::size_t>(argc));
1748-
std::copy( args.begin(), args.end(), ret.data());
1749-
return ret;
1788+
return args_t{argc, argv};
17501789
}
17511790

17521791

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,118 @@
11
mixed-bugfix-for-ufcs-non-local.cpp2:13:12: error: a lambda expression cannot appear in this context
22
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_1> bool inline constexpr v0 = false;// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context)
33
^
4-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
4+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
55
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
66
^
7-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
7+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
88
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
99
^
1010
mixed-bugfix-for-ufcs-non-local.cpp2:15:3: error: a lambda expression cannot appear in this context
1111
t<CPP2_UFCS_NONLOCAL(f)(o)> inline constexpr v1 = t<true>();// Fails on Clang 12 (lambda in unevaluated context).
1212
^
13-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
13+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
1414
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
1515
^
16-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
16+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
1717
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
1818
^
1919
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context
2020
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_2> auto g() -> void;
2121
^
22-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
22+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
2323
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
2424
^
25-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
25+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
2626
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
2727
^
2828
mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context
2929
auto g([[maybe_unused]] cpp2::in<t<CPP2_UFCS_NONLOCAL(f)(o)>> unnamed_param_1) -> void;
3030
^
31-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
31+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
3232
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
3333
^
34-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
34+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
3535
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
3636
^
3737
mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context
3838
[[nodiscard]] auto h() -> t<CPP2_UFCS_NONLOCAL(f)(o)>;
3939
^
40-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
40+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
4141
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
4242
^
43-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
43+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
4444
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
4545
^
4646
mixed-bugfix-for-ufcs-non-local.cpp2:31:12: error: a lambda expression cannot appear in this context
4747
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_3> using a = bool;// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context)
4848
^
49-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
49+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
5050
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
5151
^
52-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
52+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
5353
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
5454
^
5555
mixed-bugfix-for-ufcs-non-local.cpp2:33:12: error: a lambda expression cannot appear in this context
5656
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_4> auto inline constexpr b = false;// Fails on GCC ([GCC109781][]).
5757
^
58-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
58+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
5959
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
6060
^
61-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
61+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
6262
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
6363
^
6464
mixed-bugfix-for-ufcs-non-local.cpp2:35:13: error: a lambda expression cannot appear in this context
6565
using c = t<CPP2_UFCS_NONLOCAL(f)(o)>;// Fails on Clang 12 (lambda in unevaluated context) and Clang 12 (a lambda expression cannot appear in this context)
6666
^
67-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
67+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
6868
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
6969
^
70-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
70+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
7171
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
7272
^
7373
mixed-bugfix-for-ufcs-non-local.cpp2:37:29: error: a lambda expression cannot appear in this context
7474
auto inline constexpr d = t<CPP2_UFCS_NONLOCAL(f)(o)>();// Fails on Clang 12 (lambda in unevaluated context).
7575
^
76-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
76+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
7777
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
7878
^
79-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
79+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
8080
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
8181
^
8282
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context
8383
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_2> auto g() -> void{}// Fails on GCC ([GCC109781][]) and Clang 12 (a lambda expression cannot appear in this context)
8484
^
85-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
85+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
8686
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
8787
^
88-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
88+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
8989
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
9090
^
9191
mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context
9292
auto g([[maybe_unused]] cpp2::in<t<CPP2_UFCS_NONLOCAL(f)(o)>> unnamed_param_1) -> void{}// Fails on Clang 12 (lambda in unevaluated context).
9393
^
94-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
94+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
9595
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
9696
^
97-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
97+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
9898
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
9999
^
100100
mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context
101101
[[nodiscard]] auto h() -> t<CPP2_UFCS_NONLOCAL(f)(o)> { return o; }// Fails on Clang 12 (lambda in unevaluated context).
102102
^
103-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
103+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
104104
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
105105
^
106-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
106+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
107107
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
108108
^
109109
mixed-bugfix-for-ufcs-non-local.cpp2:41:79: error: lambda expression in an unevaluated operand
110110
inline CPP2_CONSTEXPR bool u::c = [](cpp2::in<std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(f)(o))>> x) mutable -> auto { return x; }(true);// Fails on Clang 12 (lambda in unevaluated context).
111111
^
112-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
112+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
113113
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
114114
^
115-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
115+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
116116
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
117117
^
118118
13 errors generated.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
pure2-bugfix-for-ufcs-noexcept.cpp2:5:26: error: lambda expression in an unevaluated operand
22
static_assert(noexcept(CPP2_UFCS(swap)(t(), t())));// Fails on Clang 12 (lambda in unevaluated context) and GCC 10 (static assertion failed)
33
^
4-
../../../include/cpp2util.h:929:59: note: expanded from macro 'CPP2_UFCS'
4+
../../../include/cpp2util.h:942:59: note: expanded from macro 'CPP2_UFCS'
55
#define CPP2_UFCS(...) CPP2_UFCS_(&,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
66
^
7-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
7+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
88
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
99
^
1010
1 error generated.
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand
22
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(a)(T()))>;
33
^
4-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
4+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
55
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
66
^
7-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
7+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
88
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
99
^
1010
pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand
1111
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(a)(T()))>{}// Fails on Clang 12 (lambda in unevaluated context).
1212
^
13-
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
13+
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
1414
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
1515
^
16-
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
16+
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
1717
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
1818
^
1919
2 errors generated.

0 commit comments

Comments
 (0)