#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace llarp { namespace config { // Base class for the following option flag types struct option_flag {}; struct Required_t : option_flag {}; struct Hidden_t : option_flag {}; struct MultiValue_t : option_flag {}; struct RelayOnly_t : option_flag {}; struct ClientOnly_t : option_flag {}; struct Deprecated_t : option_flag {}; /// Value to pass for an OptionDefinition to indicate that the option is required inline constexpr Required_t Required{}; /// Value to pass for an OptionDefinition to indicate that the option should be hidden from the /// generate config file if it is unset (and has no comment). Typically for deprecated, renamed /// options that still do something, and for internal dev options that aren't usefully exposed. /// (For do-nothing deprecated options use Deprecated instead). inline constexpr Hidden_t Hidden{}; /// Value to pass for an OptionDefinition to indicate that the option takes multiple values inline constexpr MultiValue_t MultiValue{}; /// Value to pass for an option that should only be set for relay configs. If found in a client /// config it be ignored (but will produce a warning). inline constexpr RelayOnly_t RelayOnly{}; /// Value to pass for an option that should only be set for client configs. If found in a relay /// config it will be ignored (but will produce a warning). inline constexpr ClientOnly_t ClientOnly{}; /// Value to pass for an option that is deprecated and does nothing and should be ignored (with /// a deprecation warning) if specified. Note that Deprecated implies Hidden, and that /// {client,relay}-only options in a {relay,client} config are also considered Deprecated. inline constexpr Deprecated_t Deprecated{}; /// Wrapper to specify a default value to an OptionDefinition template struct Default { T val; constexpr explicit Default(T val) : val{std::move(val)} {} }; /// Adds one or more comment lines to the option definition. struct Comment { std::vector comments; explicit Comment(std::initializer_list comments) : comments{std::move(comments)} {} }; /// A convenience function that returns an acceptor which assigns to a reference. /// /// Note that this holds on to the reference; it must only be used when this is safe to do. In /// particular, a reference to a local variable may be problematic. template auto AssignmentAcceptor(T& ref) { return [&ref](T arg) { ref = std::move(arg); }; } // C++20 backport: template using remove_cvref_t = std::remove_cv_t>; template constexpr bool is_default = false; template constexpr bool is_default> = true; template constexpr bool is_default = is_default>; template constexpr bool is_default_array = false; template constexpr bool is_default_array, N>> = true; template constexpr bool is_default_array = is_default_array>; template constexpr bool is_option = std::is_base_of_v< option_flag, remove_cvref_t< Option>> or std::is_same_v or is_default