#pragma once /* * Copyright (C) 2024-present ScyllaDB */ /* * SPDX-License-Identifier: LicenseRef-ScyllaDB-Source-Available-1.0 */ #include #include #include "enum_set.hh" using namespace seastar; namespace utils { enum class optional_param_flag { user_provided, force }; using optional_param_flags_set = enum_set>; template class optional_param_base { public: using value_type = T; using flag = optional_param_flag; using flags_set = optional_param_flags_set; std::optional _value; // or implicitly provided as default by scylla flags_set _flags; public: optional_param_base() = default; explicit optional_param_base(sstring value, flags_set opts = {}) noexcept : _value(std::move(value)) , _flags(opts) {} template optional_param_base& emplace(Args... args) { _value.emplace(std::forward(args)...); return *this; } constexpr explicit operator bool() const noexcept { return has_value(); } constexpr const T* operator->() const noexcept { return &_value; } constexpr const T& operator*() const noexcept { return *_value; } constexpr bool has_value() const noexcept { return _value.has_value(); } constexpr const T& value() const noexcept { return _value.value(); } constexpr T value_or(T&& default_value) const noexcept { return _value.value_or(std::forward(default_value)); } flags_set flags() const noexcept { return _flags; } constexpr bool user_provided() const noexcept { return _flags.contains(flag::user_provided); } optional_param_base& set_user_provided(bool value = true) noexcept { if (value) { _flags.set(flag::user_provided); } else { _flags.remove(flag::user_provided); } return *this; } constexpr bool force() const noexcept { return _flags.contains(flag::force); } optional_param_base& set_force(bool value = true) { if (value) { _flags.set(flag::force); } else { _flags.remove(flag::force); } return *this; } void reset() noexcept { _value.reset(); _flags = {}; } }; using optional_param = optional_param_base; } //namespace utils template<> struct fmt::formatter : fmt::formatter { auto format(const utils::optional_param_flags_set& flags, fmt::format_context& ctx) const -> decltype(ctx.out()); }; template struct fmt::formatter> : fmt::formatter { auto format(const utils::optional_param_base& p, fmt::format_context& ctx) const -> decltype(ctx.out()) { if (p) { return fmt::format_to(ctx.out(), "{} ({})", p.value(), p.flags()); } else { return fmt::format_to(ctx.out(), "(none)"); } } };