Skip to content

Commit

Permalink
Add a pair of overloads to dynamic::setDefault
Browse files Browse the repository at this point in the history
Summary:
This is a workaround to an (already reported) bug in MSVC that results in it not considering the constructors of `dynamic` when attempting to construct the default value of a parameter if the type of the parameter is a universal reference.
It works by simply adding a pair of template specializations that cause MSVC to properly construct the default value.
This also removes the default value on the universal reference version, as the only things that should be using that overload now are non-dynamic values.

Reviewed By: yfeldblum

Differential Revision: D3704990

fbshipit-source-id: 7b85c4e48a1a1023bc2fe0a76a9632b11c4e9364
  • Loading branch information
Orvid authored and Facebook Github Bot 2 committed Aug 15, 2016
1 parent 4d932ec commit df66f27
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 2 deletions.
11 changes: 11 additions & 0 deletions folly/dynamic-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,17 @@ template<class K, class V> inline dynamic& dynamic::setDefault(K&& k, V&& v) {
std::forward<V>(v))).first->second;
}

template<class K> inline dynamic& dynamic::setDefault(K&& k, dynamic&& v) {
auto& obj = get<ObjectImpl>();
return obj.insert(std::make_pair(std::forward<K>(k),
std::move(v))).first->second;
}

template<class K> inline dynamic& dynamic::setDefault(K&& k, const dynamic& v) {
auto& obj = get<ObjectImpl>();
return obj.insert(std::make_pair(std::forward<K>(k), v)).first->second;
}

inline dynamic* dynamic::get_ptr(dynamic const& idx) & {
return const_cast<dynamic*>(const_cast<dynamic const*>(this)->get_ptr(idx));
}
Expand Down
12 changes: 10 additions & 2 deletions folly/dynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,16 @@ struct dynamic : private boost::operators<dynamic> {
dynamic getDefault(const dynamic& k, dynamic&& v) const&;
dynamic getDefault(const dynamic& k, const dynamic& v = dynamic::object) &&;
dynamic getDefault(const dynamic& k, dynamic&& v) &&;
template<class K, class V = dynamic>
dynamic& setDefault(K&& k, V&& v = dynamic::object);
template<class K, class V>
dynamic& setDefault(K&& k, V&& v);
// MSVC 2015 Update 3 needs these extra overloads because if V were a
// defaulted template parameter, it causes MSVC to consider v an rvalue
// reference rather than a universal reference, resulting in it not being
// able to find the correct overload to construct a dynamic with.
template<class K>
dynamic& setDefault(K&& k, dynamic&& v);
template<class K>
dynamic& setDefault(K&& k, const dynamic& v = dynamic::object);

/*
* Resizes an array so it has at n elements, using the supplied
Expand Down

0 comments on commit df66f27

Please sign in to comment.