Changed ArgMap to be backed by a vector instead of a map.

The main reason for this is to avoid a dynamic memory allocation in every format() call with Visual Studio if there are no named arguments.
This commit is contained in:
Michael Winterberg 2016-01-10 15:30:34 -08:00
parent 97e9ed11bc
commit 4af764d040
2 changed files with 12 additions and 6 deletions

View File

@ -616,7 +616,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
map_.insert(Pair(named_arg->name, *named_arg));
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
@ -628,7 +628,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
internal::Arg::Type arg_type = args.type(i);
if (arg_type == internal::Arg::NAMED_ARG) {
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.insert(Pair(named_arg->name, *named_arg));
map_.push_back(Pair(named_arg->name, *named_arg));
}
}
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
@ -637,7 +637,7 @@ void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.insert(Pair(named_arg->name, *named_arg));
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;

View File

@ -36,7 +36,8 @@
#include <memory>
#include <stdexcept>
#include <string>
#include <map>
#include <vector>
#include <utility>
#ifndef FMT_USE_IOSTREAMS
# define FMT_USE_IOSTREAMS 1
@ -1671,7 +1672,7 @@ namespace internal {
template <typename Char>
class ArgMap {
private:
typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType;
typedef std::vector<std::pair<fmt::BasicStringRef<Char>, internal::Arg> > MapType;
typedef typename MapType::value_type Pair;
MapType map_;
@ -1680,7 +1681,12 @@ class ArgMap {
FMT_API void init(const ArgList &args);
const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const {
typename MapType::const_iterator it = map_.find(name);
typename MapType::const_iterator it = map_.begin();
// the list is unsorted, so just return the first matching name.
for (; it != map_.end(); ++it) {
if (it->first == name)
break;
}
return it != map_.end() ? &it->second : 0;
}
};