diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj b/src/beast/Builds/VisualStudio2013/beast.vcxproj
index 8ab2ece8d..5faea2bfd 100644
--- a/src/beast/Builds/VisualStudio2013/beast.vcxproj
+++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj
@@ -253,6 +253,7 @@
+
@@ -767,7 +768,7 @@
true
true
-
+
true
true
true
diff --git a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
index d5bc57a8e..80a737e81 100644
--- a/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
+++ b/src/beast/Builds/VisualStudio2013/beast.vcxproj.filters
@@ -1201,6 +1201,9 @@
beast\utility
+
+ beast\utility
+
@@ -1647,9 +1650,6 @@
beast\threads\tests
-
- beast\utility\tests
-
beast\crypto\tests
@@ -1665,6 +1665,9 @@
beast\container\impl
+
+ beast\utility\tests
+
diff --git a/src/beast/beast/utility/Zero.h b/src/beast/beast/utility/Zero.h
index 6a11f2ee7..0cd1c950b 100644
--- a/src/beast/beast/utility/Zero.h
+++ b/src/beast/beast/utility/Zero.h
@@ -22,6 +22,9 @@
#include "../config/CompilerConfig.h"
+// VS2013 SP1 fails with decltype return
+#define BEAST_NO_ZERO_AUTO_RETURN 1
+
namespace beast {
/** Zero allows classes to offer efficient comparisons to zero.
@@ -39,102 +42,122 @@ namespace beast {
returns a positive number, 0, or a negative; or there needs to be a signum
function which resolves in the namespace which takes an instance of T and
returns a positive, zero or negative number.
- */
+*/
-struct Zero {};
+struct Zero
+{
+};
namespace {
-
static BEAST_CONSTEXPR Zero zero{};
+}
-} // namespace
-
-/** The default implementation of signum calls the method on the class.
-
- Calls to signum must be made from a namespace that does not include
- overloads of the function.
- */
+/** Default implementation of signum calls the method on the class. */
template
-auto signum(T const& t) -> decltype(t.signum()) {
+#if BEAST_NO_ZERO_AUTO_RETURN
+int signum(T const& t)
+#else
+auto signum(T const& t) -> decltype(t.signum())
+#endif
+{
return t.signum();
}
namespace detail {
namespace zero_helper {
+// For argument dependent lookup to function properly, calls to signum must
+// be made from a namespace that does not include overloads of the function..
template
-auto call_signum (T const& t) -> decltype(signum(t)) {
+#if BEAST_NO_ZERO_AUTO_RETURN
+int call_signum (T const& t)
+#else
+auto call_signum(T const& t) -> decltype(t.signum())
+#endif
+{
return signum(t);
}
} // zero_helper
} // detail
-/** Handle operators where T is on the left side using signum. */
+// Handle operators where T is on the left side using signum.
+
template
-bool operator==(T const& t, Zero) {
+bool operator==(T const& t, Zero)
+{
return detail::zero_helper::call_signum(t) == 0;
}
template
-bool operator!=(T const& t, Zero) {
+bool operator!=(T const& t, Zero)
+{
return detail::zero_helper::call_signum(t) != 0;
}
template
-bool operator>(T const& t, Zero) {
- return detail::zero_helper::call_signum(t) > 0;
-}
-
-template
-bool operator>=(T const& t, Zero) {
- return detail::zero_helper::call_signum(t) >= 0;
-}
-
-template
-bool operator<(T const& t, Zero) {
+bool operator<(T const& t, Zero)
+{
return detail::zero_helper::call_signum(t) < 0;
}
template
-bool operator<=(T const& t, Zero) {
+bool operator>(T const& t, Zero)
+{
+ return detail::zero_helper::call_signum(t) > 0;
+}
+
+template
+bool operator>=(T const& t, Zero)
+{
+ return detail::zero_helper::call_signum(t) >= 0;
+}
+
+template
+bool operator<=(T const& t, Zero)
+{
return detail::zero_helper::call_signum(t) <= 0;
}
+// Handle operators where T is on the right side by
+// reversing the operation, so that T is on the left side.
-/** Handle operators where T is on the right side by reversing the operation,
- so that T is on the left side.
- */
template
-bool operator==(Zero, T const& t) {
+bool operator==(Zero, T const& t)
+{
return t == zero;
}
template
-bool operator!=(Zero, T const& t) {
+bool operator!=(Zero, T const& t)
+{
return t != zero;
}
template
-bool operator>(Zero, T const& t) {
- return t < zero;
-}
-
-template
-bool operator>=(Zero, T const& t) {
- return t <= zero;
-}
-
-template
-bool operator<(Zero, T const& t) {
+bool operator<(Zero, T const& t)
+{
return t > zero;
}
template
-bool operator<=(Zero, T const& t) {
+bool operator>(Zero, T const& t)
+{
+ return t < zero;
+}
+
+template
+bool operator>=(Zero, T const& t)
+{
+ return t <= zero;
+}
+
+template
+bool operator<=(Zero, T const& t)
+{
return t >= zero;
}
-} // beast
+} // beast
#endif
diff --git a/src/beast/beast/utility/tests/Zero.test.cpp b/src/beast/beast/utility/tests/Zero.test.cpp
index 07843f8a8..d40282d7b 100644
--- a/src/beast/beast/utility/tests/Zero.test.cpp
+++ b/src/beast/beast/utility/tests/Zero.test.cpp
@@ -25,14 +25,20 @@ namespace beast {
struct adl_tester {};
-int signum (adl_tester) { return 0; }
+int signum (adl_tester)
+{
+ return 0;
+}
namespace detail {
struct adl_tester2 {};
-int signum (adl_tester2) { return 0; }
+int signum (adl_tester2)
+{
+ return 0;
+}
} // detail