diff --git a/src/cuda/rtc/compilation_options.hpp b/src/cuda/rtc/compilation_options.hpp index bdf21576..b195d9d2 100644 --- a/src/cuda/rtc/compilation_options.hpp +++ b/src/cuda/rtc/compilation_options.hpp @@ -470,11 +470,8 @@ class compilation_options_t final : } }; - namespace detail_ { -inline const char* true_or_false(bool b) { return b ? "true" : "false"; } - template struct opt_start_t { bool ever_used; @@ -497,17 +494,17 @@ MarshalTarget& operator<<(MarshalTarget& mt, detail_::opt_start_t& op return mt; } + /** - * Use the left-shift operator (<<) to render a delimited sequence of + * Uses the streaming/left-shift operator (<<) to render a delimited sequence of * command-line-argument-like options (with or without a value as relevant) - * into some target entity - which could be a buffer or a more complex - * structure. - * + * into some target entity - which could be a buffer of chars or a more complex + * structure like @ref marshalled_options_t. */ template void process( const compilation_options_t& opts, MarshalTarget& marshalled, Delimiter delimiter, - bool need_delimited_after_every_option = false) + bool need_delimiter_after_last_option = false) { detail_::opt_start_t opt_start { delimiter }; // TODO: Consider taking an option to be verbose in specifying compilation flags, and setting option values @@ -581,7 +578,7 @@ void process( } } - if (need_delimited_after_every_option) { + if (need_delimiter_after_last_option) { marshalled << opt_start; // If no options were marshalled, this does nothing } } @@ -589,7 +586,7 @@ void process( template void process( const compilation_options_t& opts, MarshalTarget& marshalled, Delimiter delimiter, - bool need_delimited_after_every_option = false) + bool need_delimiter_after_last_option = false) { detail_::opt_start_t opt_start { delimiter }; if (opts.generate_relocatable_device_code) { marshalled << opt_start << "--relocatable-device-code=true"; } @@ -675,7 +672,7 @@ void process( marshalled << opt_start << extra_opt; } - if (need_delimited_after_every_option) { + if (need_delimiter_after_last_option) { marshalled << opt_start; // If no options were marshalled, this does nothing } } @@ -685,8 +682,8 @@ inline marshalled_options_t marshal(const compilation_options_t& opts) { marshalled_options_t mo; // TODO: Can we easily determine the max number of options here? - constexpr bool need_delimiter_after_every_option { true }; - process(opts, mo, detail_::optend, need_delimiter_after_every_option); + constexpr bool need_delimiter_after_last_option { true }; + process(opts, mo, marshalled_options_t::advance_gadget{}, need_delimiter_after_last_option); return mo; } diff --git a/src/cuda/rtc/detail/marshalled_options.hpp b/src/cuda/rtc/detail/marshalled_options.hpp index 6c491f6d..e2500fd1 100644 --- a/src/cuda/rtc/detail/marshalled_options.hpp +++ b/src/cuda/rtc/detail/marshalled_options.hpp @@ -14,6 +14,19 @@ namespace cuda { namespace rtc { +namespace detail_ { + +// These two structs are streamed to a marshalled options object (see below) +// to indicate the start of a new option or the conclusion of all options, +// respectively + +template struct opt_start_t; + +template +struct is_marshalling_control : ::std::false_type {}; + +} // namespace detail_ + /** * This class is necessary for realizing everything we need from * the marshalled options: Easy access using an array of pointers, @@ -24,6 +37,8 @@ class marshalled_options_t { public: using size_type = size_t; + struct advance_gadget {}; /// triggers an advance() when streamed into an object of this class + marshalled_options_t() { option_positions.push_back(0); @@ -49,14 +64,13 @@ class marshalled_options_t { return oss.tellp() == 0; } - template + template ::type>::value>> marshalled_options_t& operator<<(T&& x) { oss << x; return *this; } - // TODO: Make a similar "stream manipulator"? marshalled_options_t& advance() { oss << '\0'; @@ -75,16 +89,19 @@ class marshalled_options_t { } }; +inline marshalled_options_t& operator<< (marshalled_options_t& mo, marshalled_options_t::advance_gadget) +{ + mo.advance(); + return mo; +} + namespace detail_ { -inline void optend() { } +template<> struct is_marshalling_control : ::std::true_type {}; -} // namespace detail_ +template +struct is_marshalling_control> : ::std::true_type {}; -inline marshalled_options_t& operator<< (marshalled_options_t& mo, decltype(detail_::optend)) -{ - mo.advance(); - return mo; } } // namespace rtc