diff --git a/jitify2.hpp b/jitify2.hpp index 485fee6..c73cc33 100644 --- a/jitify2.hpp +++ b/jitify2.hpp @@ -41,11 +41,10 @@ #ifndef JITIFY2_HPP_INCLUDE_GUARD #define JITIFY2_HPP_INCLUDE_GUARD -// This macro is used by source files generated by jitify_preprocess to avoid -// unnecessary dependencies. -#ifdef JITIFY_SERIALIZATION_ONLY - +#include +#include #include +#include #include #include #include @@ -53,6 +52,10 @@ #include #include +// This macro is used by source files generated by jitify_preprocess to avoid +// unnecessary dependencies. +#ifdef JITIFY_SERIALIZATION_ONLY + #if __cplusplus >= 201703L #include #endif @@ -99,26 +102,18 @@ #include // For __cu_demangle (requires linking with libcufilt.a) #endif -#include #include -#include #include #include #include #include -#include #include #include #include #include -#include -#include -#include #include #include -#include #include -#include #if JITIFY_THREAD_SAFE #include @@ -220,6 +215,283 @@ using StringRef = const std::string&; using StringSlice = std::string; #endif +class Option { + public: + Option() = default; + explicit Option(std::string _key, std::string _value = {}, + StringVec _repr = {}) + : key_(std::move(_key)), + value_(std::move(_value)), + repr_(std::move(_repr)) { + if (repr_.empty()) { + repr_ = {key_}; + if (!value_.empty()) { + repr_.front() += "=" + value_; + } + } + // TODO: Consider changing key and value to be views into key_and_value to + // avoid double-storage. + if (value_.empty()) { + key_and_value_ = key_; + } else { + key_and_value_.reserve(key_.size() + 1 + value_.size()); + key_and_value_.append(key_); + key_and_value_.append("="); + key_and_value_.append(value_); + } + } + + const std::string& key() const { return key_; } + const std::string& value() const { return value_; } + const std::string& key_and_value() const { return key_and_value_; } + const StringVec& original_representation() const { return repr_; } + + friend const std::string& to_string(const Option& option) { + return option.key_and_value(); + } + + friend std::ostream& operator<<(std::ostream& os, const Option& option) { + return os << option.key_and_value(); + } + + friend bool operator==(const Option& lhs, const Option& rhs) { + return lhs.key_ == rhs.key_ && lhs.value_ == rhs.value_; + } + friend bool operator!=(const Option& lhs, const Option& rhs) { + return !(lhs == rhs); + } + + private: + std::string key_; + std::string value_; + std::string key_and_value_; + StringVec repr_; +}; + +namespace detail { + +// Strip whitespace from string in-place. +inline void ltrim(std::string* s) { + s->erase(s->begin(), std::find_if(s->begin(), s->end(), [](unsigned char c) { + return !std::isspace(c); + })); +} +inline void rtrim(std::string* s) { + s->erase(std::find_if(s->rbegin(), s->rend(), + [](unsigned char c) { return !std::isspace(c); }) + .base(), + s->end()); +} +inline void trim(std::string* s) { + ltrim(s); + rtrim(s); +} + +// Strip whitespace from a string view. +inline StringSlice ltrim(StringRef s) { + size_t beg = std::find_if(s.begin(), s.end(), + [](unsigned char c) { return !std::isspace(c); }) - + s.begin(); + return s.substr(beg); +} +inline StringSlice rtrim(StringRef s) { + size_t end = std::find_if(s.rbegin(), s.rend(), + [](unsigned char c) { return !std::isspace(c); }) + .base() - + s.begin(); + return s.substr(0, end); +} +inline StringSlice trim(StringRef s) { return rtrim(ltrim(s)); } + +} // namespace detail + +class OptionsVec { + using vec_type = std::vector