Added missing args.h file
This commit is contained in:
		
							
								
								
									
										232
									
								
								include/spdlog/fmt/bundled/args.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								include/spdlog/fmt/bundled/args.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,232 @@
 | 
			
		||||
// Formatting library for C++ - dynamic format arguments
 | 
			
		||||
//
 | 
			
		||||
// Copyright (c) 2012 - present, Victor Zverovich
 | 
			
		||||
// All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// For the license information refer to format.h.
 | 
			
		||||
 | 
			
		||||
#ifndef FMT_ARGS_H_
 | 
			
		||||
#define FMT_ARGS_H_
 | 
			
		||||
 | 
			
		||||
#include <functional>  // std::reference_wrapper
 | 
			
		||||
#include <memory>      // std::unique_ptr
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "core.h"
 | 
			
		||||
 | 
			
		||||
FMT_BEGIN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template <typename T> struct is_reference_wrapper : std::false_type {};
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};
 | 
			
		||||
 | 
			
		||||
template <typename T> const T& unwrap(const T& v) { return v; }
 | 
			
		||||
template <typename T> const T& unwrap(const std::reference_wrapper<T>& v) {
 | 
			
		||||
  return static_cast<const T&>(v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class dynamic_arg_list {
 | 
			
		||||
  // Workaround for clang's -Wweak-vtables. Unlike for regular classes, for
 | 
			
		||||
  // templates it doesn't complain about inability to deduce single translation
 | 
			
		||||
  // unit for placing vtable. So storage_node_base is made a fake template.
 | 
			
		||||
  template <typename = void> struct node {
 | 
			
		||||
    virtual ~node() = default;
 | 
			
		||||
    std::unique_ptr<node<>> next;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T> struct typed_node : node<> {
 | 
			
		||||
    T value;
 | 
			
		||||
 | 
			
		||||
    template <typename Arg>
 | 
			
		||||
    FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}
 | 
			
		||||
 | 
			
		||||
    template <typename Char>
 | 
			
		||||
    FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)
 | 
			
		||||
        : value(arg.data(), arg.size()) {}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  std::unique_ptr<node<>> head_;
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  template <typename T, typename Arg> const T& push(const Arg& arg) {
 | 
			
		||||
    auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));
 | 
			
		||||
    auto& value = new_node->value;
 | 
			
		||||
    new_node->next = std::move(head_);
 | 
			
		||||
    head_ = std::move(new_node);
 | 
			
		||||
    return value;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
  \rst
 | 
			
		||||
  A dynamic version of `fmt::format_arg_store`.
 | 
			
		||||
  It's equipped with a storage to potentially temporary objects which lifetimes
 | 
			
		||||
  could be shorter than the format arguments object.
 | 
			
		||||
 | 
			
		||||
  It can be implicitly converted into `~fmt::basic_format_args` for passing
 | 
			
		||||
  into type-erased formatting functions such as `~fmt::vformat`.
 | 
			
		||||
  \endrst
 | 
			
		||||
 */
 | 
			
		||||
template <typename Context>
 | 
			
		||||
class dynamic_format_arg_store
 | 
			
		||||
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
 | 
			
		||||
    // Workaround a GCC template argument substitution bug.
 | 
			
		||||
    : public basic_format_args<Context>
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
 private:
 | 
			
		||||
  using char_type = typename Context::char_type;
 | 
			
		||||
 | 
			
		||||
  template <typename T> struct need_copy {
 | 
			
		||||
    static constexpr detail::type mapped_type =
 | 
			
		||||
        detail::mapped_type_constant<T, Context>::value;
 | 
			
		||||
 | 
			
		||||
    enum {
 | 
			
		||||
      value = !(detail::is_reference_wrapper<T>::value ||
 | 
			
		||||
                std::is_same<T, basic_string_view<char_type>>::value ||
 | 
			
		||||
                std::is_same<T, detail::std_string_view<char_type>>::value ||
 | 
			
		||||
                (mapped_type != detail::type::cstring_type &&
 | 
			
		||||
                 mapped_type != detail::type::string_type &&
 | 
			
		||||
                 mapped_type != detail::type::custom_type))
 | 
			
		||||
    };
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  using stored_type = conditional_t<detail::is_string<T>::value &&
 | 
			
		||||
                                        !has_formatter<T, Context>::value &&
 | 
			
		||||
                                        !detail::is_reference_wrapper<T>::value,
 | 
			
		||||
                                    std::basic_string<char_type>, T>;
 | 
			
		||||
 | 
			
		||||
  // Storage of basic_format_arg must be contiguous.
 | 
			
		||||
  std::vector<basic_format_arg<Context>> data_;
 | 
			
		||||
  std::vector<detail::named_arg_info<char_type>> named_info_;
 | 
			
		||||
 | 
			
		||||
  // Storage of arguments not fitting into basic_format_arg must grow
 | 
			
		||||
  // without relocation because items in data_ refer to it.
 | 
			
		||||
  detail::dynamic_arg_list dynamic_args_;
 | 
			
		||||
 | 
			
		||||
  friend class basic_format_args<Context>;
 | 
			
		||||
 | 
			
		||||
  unsigned long long get_types() const {
 | 
			
		||||
    return detail::is_unpacked_bit | data_.size() |
 | 
			
		||||
           (named_info_.empty()
 | 
			
		||||
                ? 0ULL
 | 
			
		||||
                : static_cast<unsigned long long>(detail::has_named_args_bit));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const basic_format_arg<Context>* data() const {
 | 
			
		||||
    return named_info_.empty() ? data_.data() : data_.data() + 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T> void emplace_arg(const T& arg) {
 | 
			
		||||
    data_.emplace_back(detail::make_arg<Context>(arg));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void emplace_arg(const detail::named_arg<char_type, T>& arg) {
 | 
			
		||||
    if (named_info_.empty()) {
 | 
			
		||||
      constexpr const detail::named_arg_info<char_type>* zero_ptr{nullptr};
 | 
			
		||||
      data_.insert(data_.begin(), {zero_ptr, 0});
 | 
			
		||||
    }
 | 
			
		||||
    data_.emplace_back(detail::make_arg<Context>(detail::unwrap(arg.value)));
 | 
			
		||||
    auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {
 | 
			
		||||
      data->pop_back();
 | 
			
		||||
    };
 | 
			
		||||
    std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>
 | 
			
		||||
        guard{&data_, pop_one};
 | 
			
		||||
    named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});
 | 
			
		||||
    data_[0].value_.named_args = {named_info_.data(), named_info_.size()};
 | 
			
		||||
    guard.release();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  /**
 | 
			
		||||
    \rst
 | 
			
		||||
    Adds an argument into the dynamic store for later passing to a formatting
 | 
			
		||||
    function.
 | 
			
		||||
 | 
			
		||||
    Note that custom types and string types (but not string views) are copied
 | 
			
		||||
    into the store dynamically allocating memory if necessary.
 | 
			
		||||
 | 
			
		||||
    **Example**::
 | 
			
		||||
 | 
			
		||||
      fmt::dynamic_format_arg_store<fmt::format_context> store;
 | 
			
		||||
      store.push_back(42);
 | 
			
		||||
      store.push_back("abc");
 | 
			
		||||
      store.push_back(1.5f);
 | 
			
		||||
      std::string result = fmt::vformat("{} and {} and {}", store);
 | 
			
		||||
    \endrst
 | 
			
		||||
  */
 | 
			
		||||
  template <typename T> void push_back(const T& arg) {
 | 
			
		||||
    if (detail::const_check(need_copy<T>::value))
 | 
			
		||||
      emplace_arg(dynamic_args_.push<stored_type<T>>(arg));
 | 
			
		||||
    else
 | 
			
		||||
      emplace_arg(detail::unwrap(arg));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
    \rst
 | 
			
		||||
    Adds a reference to the argument into the dynamic store for later passing to
 | 
			
		||||
    a formatting function.
 | 
			
		||||
 | 
			
		||||
    **Example**::
 | 
			
		||||
 | 
			
		||||
      fmt::dynamic_format_arg_store<fmt::format_context> store;
 | 
			
		||||
      char band[] = "Rolling Stones";
 | 
			
		||||
      store.push_back(std::cref(band));
 | 
			
		||||
      band[9] = 'c'; // Changing str affects the output.
 | 
			
		||||
      std::string result = fmt::vformat("{}", store);
 | 
			
		||||
      // result == "Rolling Scones"
 | 
			
		||||
    \endrst
 | 
			
		||||
  */
 | 
			
		||||
  template <typename T> void push_back(std::reference_wrapper<T> arg) {
 | 
			
		||||
    static_assert(
 | 
			
		||||
        need_copy<T>::value,
 | 
			
		||||
        "objects of built-in types and string views are always copied");
 | 
			
		||||
    emplace_arg(arg.get());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
    Adds named argument into the dynamic store for later passing to a formatting
 | 
			
		||||
    function. ``std::reference_wrapper`` is supported to avoid copying of the
 | 
			
		||||
    argument. The name is always copied into the store.
 | 
			
		||||
  */
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  void push_back(const detail::named_arg<char_type, T>& arg) {
 | 
			
		||||
    const char_type* arg_name =
 | 
			
		||||
        dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();
 | 
			
		||||
    if (detail::const_check(need_copy<T>::value)) {
 | 
			
		||||
      emplace_arg(
 | 
			
		||||
          fmt::arg(arg_name, dynamic_args_.push<stored_type<T>>(arg.value)));
 | 
			
		||||
    } else {
 | 
			
		||||
      emplace_arg(fmt::arg(arg_name, arg.value));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Erase all elements from the store */
 | 
			
		||||
  void clear() {
 | 
			
		||||
    data_.clear();
 | 
			
		||||
    named_info_.clear();
 | 
			
		||||
    dynamic_args_ = detail::dynamic_arg_list();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
    \rst
 | 
			
		||||
    Reserves space to store at least *new_cap* arguments including
 | 
			
		||||
    *new_cap_named* named arguments.
 | 
			
		||||
    \endrst
 | 
			
		||||
  */
 | 
			
		||||
  void reserve(size_t new_cap, size_t new_cap_named) {
 | 
			
		||||
    FMT_ASSERT(new_cap >= new_cap_named,
 | 
			
		||||
               "Set of arguments includes set of named arguments");
 | 
			
		||||
    data_.reserve(new_cap);
 | 
			
		||||
    named_info_.reserve(new_cap_named);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
FMT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#endif  // FMT_ARGS_H_
 | 
			
		||||
		Reference in New Issue
	
	Block a user