.. _program_listing_file_uri-template_Template.h: Program Listing for File Template.h =================================== |exhale_lsh| :ref:`Return to documentation for file ` (``uri-template/Template.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include "Operator.h" #include "Variable.h" namespace URI { namespace Template { namespace detail { // NOLINT(readability-identifier-naming) template struct typelist; } class Literal { public: static const std::unordered_set kNotAllowedChars; Literal(std::string&& lit_string); Literal(const Literal&) = default; Literal& operator=(const Literal&) = default; Literal(Literal&&) noexcept = default; Literal& operator=(Literal&&) noexcept = default; ~Literal() = default; std::size_t Size() const; const std::string& String() const noexcept; bool operator==(const Literal& rhs) const; bool operator!=(const Literal& rhs) const; private: std::string lit_string_; }; class Expression { public: Expression(std::shared_ptr&& oper, std::vector&& variables); Expression(const Expression&) = default; Expression& operator=(const Expression&) = default; Expression(Expression&&) noexcept = default; Expression& operator=(Expression&&) noexcept = default; ~Expression() = default; const Operator& Oper() const; const std::vector& Vars() const; std::string String() const noexcept; bool operator==(const Expression& rhs) const; bool operator!=(const Expression& rhs) const; private: std::shared_ptr oper_; std::vector var_list_; }; enum class PartType { LITERAL, EXPRESSION }; class Part { public: template , detail::typelist...>>::value>> Part(Args&&... args) : part_(std::forward(args)...) { if (std::holds_alternative(part_)) { type_ = PartType::LITERAL; } else { type_ = PartType::EXPRESSION; } } Part(const Part&) = default; Part& operator=(const Part&) = default; Part(Part&&) noexcept = default; Part& operator=(Part&&) noexcept = default; ~Part() = default; template T& Get() { return std::get(part_); } template const T& Get() const { return std::get(part_); } inline PartType Type() const { return type_; } inline std::string String() const noexcept { if (std::holds_alternative(part_)) { return Get().String(); } return Get().String(); } inline bool operator==(const Part& rhs) const { return type_ == rhs.type_ && part_ == rhs.part_; } inline bool operator!=(const Part& rhs) const { return !(*this == rhs); } private: PartType type_; std::variant part_; }; class Template { public: Template() = default; Template(const Template&) = default; Template& operator=(const Template&) = default; Template(Template&&) noexcept = default; Template& operator=(Template&&) noexcept = default; ~Template() = default; template Part& EmplaceBack(Args&&... args) { return parts_.emplace_back(std::forward(args)...); } bool IsTemplated() const; std::size_t Size() const; std::vector& Parts(); const std::vector& Parts() const; Part& operator[](std::size_t pos); const Part& operator[](std::size_t pos) const; std::string String() const noexcept; private: std::vector parts_; }; } // namespace Template } // namespace URI