X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fdynamic-inl.h;h=7b187d7c88509df00f6fafc1bcc459c58fa982fd;hp=909c5b28204f664b4199bb631f686ff47b70e66c;hb=4bec077b3dc283e75125e9cf95fad89ca6617101;hpb=864eb2a656ecfe1c5a7ba05e7b5bd3b67db66ae5 diff --git a/folly/dynamic-inl.h b/folly/dynamic-inl.h index 909c5b28..7b187d7c 100644 --- a/folly/dynamic-inl.h +++ b/folly/dynamic-inl.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,24 +17,26 @@ #pragma once #include + #include #include -#include + #include #include +#include ////////////////////////////////////////////////////////////////////// namespace std { -template<> -struct hash< ::folly::dynamic> { +template <> +struct hash<::folly::dynamic> { size_t operator()(::folly::dynamic const& d) const { return d.hash(); } }; -} +} // namespace std ////////////////////////////////////////////////////////////////////// @@ -44,7 +46,7 @@ struct hash< ::folly::dynamic> { do { \ switch ((type)) { \ case NULLT: \ - apply(void*); \ + apply(std::nullptr_t); \ break; \ case ARRAY: \ apply(Array); \ @@ -76,83 +78,57 @@ namespace folly { struct TypeError : std::runtime_error { explicit TypeError(const std::string& expected, dynamic::Type actual); - explicit TypeError(const std::string& expected, - dynamic::Type actual1, dynamic::Type actual2); - ~TypeError(); + explicit TypeError( + const std::string& expected, + dynamic::Type actual1, + dynamic::Type actual2); + ~TypeError() override; }; +[[noreturn]] void throwTypeError_( + std::string const& expected, + dynamic::Type actual); +[[noreturn]] void throwTypeError_( + std::string const& expected, + dynamic::Type actual1, + dynamic::Type actual2); ////////////////////////////////////////////////////////////////////// namespace detail { - // This helper is used in destroy() to be able to run destructors on - // types like "int64_t" without a compiler error. - struct Destroy { - template static void destroy(T* t) { t->~T(); } - }; - - /* - * The enable_if junk here is necessary to avoid ambiguous - * conversions relating to bool and double when you implicitly - * convert an int or long to a dynamic. - */ - template struct ConversionHelper; - template - struct ConversionHelper< - T, - typename std::enable_if< - std::is_integral::value && !std::is_same::value - >::type - > { - typedef int64_t type; - }; - template <> - struct ConversionHelper { - typedef double type; - }; +// This helper is used in destroy() to be able to run destructors on +// types like "int64_t" without a compiler error. +struct Destroy { template - struct ConversionHelper< - T, - typename std::enable_if< - (!std::is_integral::value || std::is_same::value) && - !std::is_same::value && - !std::is_same::value>::type> { - typedef T type; - }; - template - struct ConversionHelper< - T, - typename std::enable_if< - std::is_same::value - >::type - > { - typedef void* type; - }; - - /* - * Helper for implementing numeric conversions in operators on - * numbers. Just promotes to double when one of the arguments is - * double, or throws if either is not a numeric type. - */ - template class Op> - dynamic numericOp(dynamic const& a, dynamic const& b) { - if (!a.isNumber() || !b.isNumber()) { - throw TypeError("numeric", a.type(), b.type()); - } - if (a.type() != b.type()) { - auto& integ = a.isInt() ? a : b; - auto& nonint = a.isInt() ? b : a; - return Op()(to(integ.asInt()), nonint.asDouble()); - } - if (a.isDouble()) { - return Op()(a.asDouble(), b.asDouble()); - } - return Op()(a.asInt(), b.asInt()); + static void destroy(T* t) { + t->~T(); } +}; +/* + * Helper for implementing numeric conversions in operators on + * numbers. Just promotes to double when one of the arguments is + * double, or throws if either is not a numeric type. + */ +template