diff --git a/Builds/VisualStudio2013/beast.vcxproj b/Builds/VisualStudio2013/beast.vcxproj
index 40f4a29a1..45289b1f9 100644
--- a/Builds/VisualStudio2013/beast.vcxproj
+++ b/Builds/VisualStudio2013/beast.vcxproj
@@ -777,6 +777,12 @@
true
true
+
+ true
+ true
+ true
+ true
+
true
diff --git a/Builds/VisualStudio2013/beast.vcxproj.filters b/Builds/VisualStudio2013/beast.vcxproj.filters
index 080bb8b70..e91b7a526 100644
--- a/Builds/VisualStudio2013/beast.vcxproj.filters
+++ b/Builds/VisualStudio2013/beast.vcxproj.filters
@@ -321,6 +321,9 @@
{899ea9a6-1969-4cde-b26d-8ad60acebfa4}
+
+ {3c58ba5e-1855-4865-8a9f-c0afd5014e74}
+
@@ -1940,6 +1943,9 @@
beast\streams
+
+ beast\utility\tests
+
diff --git a/beast/utility/Utility.cpp b/beast/utility/Utility.cpp
index eb5d53d3f..48175d75b 100644
--- a/beast/utility/Utility.cpp
+++ b/beast/utility/Utility.cpp
@@ -32,3 +32,4 @@
#include "impl/LeakChecked.cpp"
#include "impl/StaticObject.cpp"
#include "impl/PropertyStream.cpp"
+#include "tests/empty_base_optimization.test.cpp"
diff --git a/beast/utility/empty_base_optimization.h b/beast/utility/empty_base_optimization.h
index 39f8d6895..fec1aebf1 100644
--- a/beast/utility/empty_base_optimization.h
+++ b/beast/utility/empty_base_optimization.h
@@ -24,20 +24,10 @@
#include
#include
-#ifndef BEAST_NO_EMPTY_BASE_OPTIMIZATION
-# if defined _MSC_VER
-# define BEAST_NO_EMPTY_BASE_OPTIMIZATION 1
-# else
-# define BEAST_NO_EMPTY_BASE_OPTIMIZATION 1
-# endif
-#endif
-
namespace beast {
namespace detail {
-#if ! BEAST_NO_EMPTY_BASE_OPTIMIZATION
-
template
struct empty_base_optimization_decide
: std::integral_constant
-struct empty_base_optimization_decide
- : std::false_type
-{
-};
-
-#endif
-
}
//------------------------------------------------------------------------------
@@ -72,43 +52,15 @@ template <
class empty_base_optimization : private T
{
public:
- template <
- class... Args,
- class = typename std::enable_if <
- std::is_constructible ::value>::type
- >
- explicit /*constexpr*/ empty_base_optimization (
- Args&&... args)
- /*noexcept (std::is_nothrow_constructible ::value);*/
- : T (std::forward (args)...)
- {
- }
+ empty_base_optimization() = default;
-#if 1
- empty_base_optimization (T const& t)
+ empty_base_optimization(T const& t)
: T (t)
- {
- }
+ {}
- empty_base_optimization (T&& t)
+ empty_base_optimization(T&& t)
: T (std::move (t))
- {
- }
-
- empty_base_optimization& operator= (
- empty_base_optimization const& other)
- {
- *this = other;
- return *this;
- }
-
- empty_base_optimization& operator= (
- empty_base_optimization&& other)
- {
- *this = std::move (other);
- return *this;
- }
-#endif
+ {}
T& member() noexcept
{
@@ -130,17 +82,15 @@ template <
class empty_base_optimization
{
public:
- template <
- class... Args,
- class = typename std::enable_if <
- std::is_constructible ::value>::type
- >
- explicit /*constexpr*/ empty_base_optimization (
- Args&&... args)
- /*noexcept (std::is_nothrow_constructible ::value);*/
- : m_t (std::forward (args)...)
- {
- }
+ empty_base_optimization() = default;
+
+ empty_base_optimization(T const& t)
+ : m_t (t)
+ {}
+
+ empty_base_optimization(T&& t)
+ : m_t (std::move (t))
+ {}
T& member() noexcept
{
diff --git a/beast/utility/tests/empty_base_optimization.test.cpp b/beast/utility/tests/empty_base_optimization.test.cpp
new file mode 100644
index 000000000..54c967414
--- /dev/null
+++ b/beast/utility/tests/empty_base_optimization.test.cpp
@@ -0,0 +1,113 @@
+//-------------------- empty_base_optimization.test.cpp ------------------------
+/*
+ This file is part of rippled: https://github.com/ripple/rippled
+ Copyright (c) 2014 Ripple Labs Inc.
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#if BEAST_INCLUDE_BEASTCONFIG
+#include "../../../BeastConfig.h"
+#endif
+
+#include "../empty_base_optimization.h"
+
+#include "../../../modules/beast_core/beast_core.h" // for UnitTest
+
+namespace beast {
+
+class empty_base_optimization_Tests
+ : public UnitTest
+{
+public:
+ template
+ class test1
+ : private empty_base_optimization
+ {
+ typedef empty_base_optimization Base;
+ void* m_p;
+ public:
+ explicit test1 (T const& t)
+ : Base (t)
+ {}
+
+ T& member() {return Base::member();}
+ T const& member() const {return Base::member();}
+ };
+
+ template
+ class test2
+ {
+ void* m_p;
+ T m_t;
+ public:
+ explicit test2 (T const& t)
+ : m_t (t)
+ {}
+
+ T& member() {return m_t;}
+ T const& member() const {return m_t;}
+ };
+
+ struct Empty
+ {
+ operator bool() {return true;}
+ };
+
+ static
+ bool
+ test_one ()
+ {
+ test1 t1(1);
+ test2 t2(2);
+ static_assert(sizeof(t1) == sizeof(t2), "don't optimize for int");
+ if (t1.member() != 1)
+ return false;
+ if (t2.member() != 2)
+ return false;
+ return true;
+ }
+
+ static
+ bool
+ test_two ()
+ {
+ test1 t1((Empty()));
+ test2 t2((Empty()));
+ static_assert(sizeof(t1) < sizeof(t2), "do optimize for Empty");
+ if (t1.member() != true)
+ return false;
+ if (t2.member() != true)
+ return false;
+ return true;
+ }
+
+ void
+ runTest ()
+ {
+ beginTestCase ("empty_base_optimization");
+ expect (test_one());
+ expect (test_two());
+ pass ();
+ }
+
+ empty_base_optimization_Tests()
+ : UnitTest ("empty_base_optimization", "beast")
+ {
+ }
+};
+
+static empty_base_optimization_Tests empty_base_optimization_tests;
+
+} // beast