Remove dependency on <vector> and <array>

This commit is contained in:
Victor Zverovich
2017-12-09 08:48:30 -08:00
parent 41fc29907a
commit ce801c9095
2 changed files with 27 additions and 14 deletions

View File

@ -28,12 +28,10 @@
#ifndef FMT_CORE_H_ #ifndef FMT_CORE_H_
#define FMT_CORE_H_ #define FMT_CORE_H_
#include <array>
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include <vector>
#ifdef __has_feature #ifdef __has_feature
# define FMT_HAS_FEATURE(x) __has_feature(x) # define FMT_HAS_FEATURE(x) __has_feature(x)
@ -684,6 +682,8 @@ struct named_arg : basic_arg<Context> {
template <typename Context> template <typename Context>
class arg_map { class arg_map {
private: private:
FMT_DISALLOW_COPY_AND_ASSIGN(arg_map);
using Char = typename Context::char_type; using Char = typename Context::char_type;
struct arg { struct arg {
@ -691,15 +691,23 @@ class arg_map {
basic_arg<Context> value; basic_arg<Context> value;
}; };
std::vector<arg> map_; arg *map_ = nullptr;
unsigned size_ = 0;
void push_back(arg a) {
map_[size_] = a;
++size_;
}
public: public:
arg_map() {}
void init(const basic_format_args<Context> &args); void init(const basic_format_args<Context> &args);
~arg_map() { delete [] map_; }
const basic_arg<Context> const basic_arg<Context>
*find(const fmt::basic_string_view<Char> &name) const { *find(const fmt::basic_string_view<Char> &name) const {
// The list is unsorted, so just return the first matching name. // The list is unsorted, so just return the first matching name.
for (auto it = map_.begin(), end = map_.end(); it != end; ++it) { for (auto it = map_, end = map_ + size_; it != end; ++it) {
if (it->name == name) if (it->name == name)
return &it->value; return &it->value;
} }
@ -789,21 +797,20 @@ class arg_store {
// Packed is a macro on MinGW so use IS_PACKED instead. // Packed is a macro on MinGW so use IS_PACKED instead.
static const bool IS_PACKED = NUM_ARGS < internal::MAX_PACKED_ARGS; static const bool IS_PACKED = NUM_ARGS < internal::MAX_PACKED_ARGS;
using value_type = typename std::conditional<IS_PACKED, using value_type = typename std::conditional<
internal::value<Context>, basic_arg<Context>>::type; IS_PACKED, internal::value<Context>, basic_arg<Context>>::type;
// If the arguments are not packed, add one more element to mark the end. // If the arguments are not packed, add one more element to mark the end.
using Array = std::array<value_type, NUM_ARGS + (IS_PACKED ? 0 : 1)>; value_type data_[NUM_ARGS + (IS_PACKED ? 0 : 1)];
Array data_;
public: public:
static const uint64_t TYPES = IS_PACKED ? static const uint64_t TYPES = IS_PACKED ?
internal::get_types<Args..., void>() : -static_cast<int64_t>(NUM_ARGS); internal::get_types<Args..., void>() : -static_cast<int64_t>(NUM_ARGS);
arg_store(const Args &... args) arg_store(const Args &... args)
: data_(Array{{internal::make_arg<IS_PACKED, Context>(args)...}}) {} : data_{internal::make_arg<IS_PACKED, Context>(args)...} {}
const value_type *data() const { return data_.data(); } const value_type *data() const { return data_; }
}; };
template <typename Context, typename ...Args> template <typename Context, typename ...Args>
@ -881,6 +888,11 @@ class basic_format_args {
return arg.type_ == internal::NAMED_ARG ? return arg.type_ == internal::NAMED_ARG ?
*static_cast<const format_arg*>(arg.value_.pointer) : arg; *static_cast<const format_arg*>(arg.value_.pointer) : arg;
} }
unsigned max_size() const {
int64_t signed_types = static_cast<int64_t>(types_);
return signed_types < 0 ? -signed_types : internal::MAX_PACKED_ARGS;
}
}; };
using format_args = basic_format_args<context>; using format_args = basic_format_args<context>;

View File

@ -1167,8 +1167,9 @@ class cstring_type_checker : public ErrorHandler {
template <typename Context> template <typename Context>
void arg_map<Context>::init(const basic_format_args<Context> &args) { void arg_map<Context>::init(const basic_format_args<Context> &args) {
if (!map_.empty()) if (map_)
return; return;
map_ = new arg[args.max_size()];
typedef internal::named_arg<Context> NamedArg; typedef internal::named_arg<Context> NamedArg;
const NamedArg *named_arg = 0; const NamedArg *named_arg = 0;
bool use_values = bool use_values =
@ -1181,7 +1182,7 @@ void arg_map<Context>::init(const basic_format_args<Context> &args) {
return; return;
case internal::NAMED_ARG: case internal::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer); named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
map_.push_back(arg{named_arg->name, *named_arg}); push_back(arg{named_arg->name, *named_arg});
break; break;
default: default:
break; // Do nothing. break; // Do nothing.
@ -1193,7 +1194,7 @@ void arg_map<Context>::init(const basic_format_args<Context> &args) {
internal::type arg_type = args.type(i); internal::type arg_type = args.type(i);
if (arg_type == internal::NAMED_ARG) { if (arg_type == internal::NAMED_ARG) {
named_arg = static_cast<const NamedArg*>(args.args_[i].value_.pointer); named_arg = static_cast<const NamedArg*>(args.args_[i].value_.pointer);
map_.push_back(arg{named_arg->name, *named_arg}); push_back(arg{named_arg->name, *named_arg});
} }
} }
for (unsigned i = MAX_PACKED_ARGS; ; ++i) { for (unsigned i = MAX_PACKED_ARGS; ; ++i) {
@ -1202,7 +1203,7 @@ void arg_map<Context>::init(const basic_format_args<Context> &args) {
return; return;
case internal::NAMED_ARG: case internal::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.args_[i].value_.pointer); named_arg = static_cast<const NamedArg*>(args.args_[i].value_.pointer);
map_.push_back(arg{named_arg->name, *named_arg}); push_back(arg{named_arg->name, *named_arg});
break; break;
default: default:
break; // Do nothing. break; // Do nothing.