Skip to content

Commit

Permalink
Make main(args) zero-allocation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
hsutter committed Feb 5, 2024
1 parent 510eae8 commit 6af78c9
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 59 deletions.
53 changes: 46 additions & 7 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1729,24 +1729,63 @@ class finally_presuccess

//-----------------------------------------------------------------------
//
// args: see main() arguments as vector<string_view>
// args: see main() arguments as a container of string_views
//
// Does not perform any dynamic memory allocation - each string_view
// is directly bound to the string provided by the host environment
//
//-----------------------------------------------------------------------
//
struct args_t : std::vector<std::string_view>
struct args_t
{
args_t(int c, char** v) : vector{static_cast<std::size_t>(c)}, argc{c}, argv{v} {}
args_t(int c, char** v) : argc{c}, argv{v} {}

class iterator {
public:
iterator(int c, char** v, int start) : argc{c}, argv{v}, curr{start} {}

auto operator*() const {
if (curr < argc) { return std::string_view{ argv[curr] }; }
else { return std::string_view{}; }
}

auto operator+(int i) -> iterator {
if (i > 0) { return { argc, argv, std::min(curr+i, argc) }; }
else { return { argc, argv, std::max(curr+i, 0 ) }; }
}
auto operator-(int i) -> iterator { return operator+(-i); }
auto operator++() -> iterator& { curr = std::min(curr+1, argc); return *this; }
auto operator--() -> iterator& { curr = std::max(curr-1, 0 ); return *this; }
auto operator++(int) -> iterator { auto old = *this; ++*this; return old; }
auto operator--(int) -> iterator { auto old = *this; ++*this; return old; }

auto operator<=>(iterator const&) const = default;

private:
int argc;
char** argv;
int curr;
};

auto begin() const -> iterator { return iterator{ argc, argv, 0 }; }
auto end() const -> iterator { return iterator{ argc, argv, argc }; }
auto cbegin() const -> iterator { return begin(); }
auto cend() const -> iterator { return end(); }
auto size() const -> std::size_t { return argc; }
auto ssize() const -> int { return argc; }

auto operator[](int i) const {
if (0 <= i && i < argc) { return std::string_view{ argv[i] }; }
else { return std::string_view{}; }
}

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

inline auto make_args(int argc, char** argv) -> args_t
{
auto ret = args_t{argc, argv};
auto args = std::span(argv, static_cast<std::size_t>(argc));
std::copy( args.begin(), args.end(), ret.data());
return ret;
return args_t{argc, argv};
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,118 +1,118 @@
mixed-bugfix-for-ufcs-non-local.cpp2:13:12: error: a lambda expression cannot appear in this context
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)
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:15:3: error: a lambda expression cannot appear in this context
t<CPP2_UFCS_NONLOCAL(f)(o)> inline constexpr v1 = t<true>();// Fails on Clang 12 (lambda in unevaluated context).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_2> auto g() -> void;
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context
auto g([[maybe_unused]] cpp2::in<t<CPP2_UFCS_NONLOCAL(f)(o)>> unnamed_param_1) -> void;
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context
[[nodiscard]] auto h() -> t<CPP2_UFCS_NONLOCAL(f)(o)>;
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:31:12: error: a lambda expression cannot appear in this context
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)
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:33:12: error: a lambda expression cannot appear in this context
template<t<CPP2_UFCS_NONLOCAL(f)(o)> UnnamedTypeParam1_4> auto inline constexpr b = false;// Fails on GCC ([GCC109781][]).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:35:13: error: a lambda expression cannot appear in this context
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)
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:37:29: error: a lambda expression cannot appear in this context
auto inline constexpr d = t<CPP2_UFCS_NONLOCAL(f)(o)>();// Fails on Clang 12 (lambda in unevaluated context).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: error: a lambda expression cannot appear in this context
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)
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:23:36: error: a lambda expression cannot appear in this context
auto g([[maybe_unused]] cpp2::in<t<CPP2_UFCS_NONLOCAL(f)(o)>> unnamed_param_1) -> void{}// Fails on Clang 12 (lambda in unevaluated context).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:27:29: error: a lambda expression cannot appear in this context
[[nodiscard]] auto h() -> t<CPP2_UFCS_NONLOCAL(f)(o)> { return o; }// Fails on Clang 12 (lambda in unevaluated context).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
mixed-bugfix-for-ufcs-non-local.cpp2:41:79: error: lambda expression in an unevaluated operand
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).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
13 errors generated.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pure2-bugfix-for-ufcs-noexcept.cpp2:5:26: error: lambda expression in an unevaluated operand
static_assert(noexcept(CPP2_UFCS(swap)(t(), t())));// Fails on Clang 12 (lambda in unevaluated context) and GCC 10 (static assertion failed)
^
../../../include/cpp2util.h:929:59: note: expanded from macro 'CPP2_UFCS'
../../../include/cpp2util.h:942:59: note: expanded from macro 'CPP2_UFCS'
#define CPP2_UFCS(...) CPP2_UFCS_(&,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
1 error generated.
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(a)(T()))>;
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
pure2-bugfix-for-ufcs-sfinae.cpp2:1:78: error: lambda expression in an unevaluated operand
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS_NONLOCAL(a)(T()))>{}// Fails on Clang 12 (lambda in unevaluated context).
^
../../../include/cpp2util.h:934:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
../../../include/cpp2util.h:947:59: note: expanded from macro 'CPP2_UFCS_NONLOCAL'
#define CPP2_UFCS_NONLOCAL(...) CPP2_UFCS_(,CPP2_UFCS_IDENTITY,(),,__VA_ARGS__)
^
../../../include/cpp2util.h:913:59: note: expanded from macro 'CPP2_UFCS_'
../../../include/cpp2util.h:926:59: note: expanded from macro 'CPP2_UFCS_'
#define CPP2_UFCS_(LAMBDADEFCAPT,MVFWD,QUALID,TEMPKW,...) \
^
2 errors generated.
Loading

0 comments on commit 6af78c9

Please sign in to comment.