diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index e8e69db1f..75b4e225c 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -987,6 +987,9 @@
True
+
+ True
+
True
@@ -999,6 +1002,8 @@
+
+
True
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index 7224346d2..d5af87b59 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -1674,6 +1674,9 @@
beast\utility\tests
+
+ beast\utility\tests
+
beast\utility\tests
@@ -1689,6 +1692,9 @@
beast
+
+ beast
+
hyperleveldb\db
diff --git a/src/beast/beast/utility/Utility.unity.cpp b/src/beast/beast/utility/Utility.unity.cpp
index d33f23ee4..71ce60e47 100644
--- a/src/beast/beast/utility/Utility.unity.cpp
+++ b/src/beast/beast/utility/Utility.unity.cpp
@@ -33,4 +33,5 @@
#include
#include
#include
+#include
#include
diff --git a/src/beast/beast/utility/tests/weak_fn.test.cpp b/src/beast/beast/utility/tests/weak_fn.test.cpp
new file mode 100644
index 000000000..7137fc978
--- /dev/null
+++ b/src/beast/beast/utility/tests/weak_fn.test.cpp
@@ -0,0 +1,146 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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.
+*/
+//==============================================================================
+
+#include
+#include
+
+namespace beast {
+
+class weak_fn_test : public beast::unit_test::suite
+{
+public:
+ struct T
+ {
+ bool& called_;
+
+ explicit
+ T (bool& called)
+ : called_(called)
+ {
+ }
+
+ void
+ fv()
+ {
+ called_ = true;
+ }
+
+ void
+ fi(int i)
+ {
+ called_ = true;
+ }
+
+ void
+ fis(int, std::string)
+ {
+ called_ = true;
+ }
+
+ int
+ fri()
+ {
+ called_ = true;
+ return 2;
+ }
+ };
+
+ void
+ run()
+ {
+ {
+ bool called = false;
+ auto const p = std::make_shared(called);
+ std::bind(weak_fn(&T::fv, p))();
+ expect(called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ auto call = std::bind(weak_fn(&T::fv, p));
+ p.reset();
+ call();
+ expect(! called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ std::bind(weak_fn(&T::fi, p), 1)();
+ expect(called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ std::bind(weak_fn(&T::fi, p),
+ std::placeholders::_1)(1);
+ expect(called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ std::bind(weak_fn(&T::fis, p),
+ 1, std::placeholders::_1)("foo");
+ expect(called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ try
+ {
+ std::bind(weak_fn(&T::fis, p, throw_if_invalid<>()),
+ 1, std::placeholders::_1)("foo");
+ p.reset();
+ fail();
+ }
+ catch(std::bad_weak_ptr const&)
+ {
+ expect(! called);
+ }
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ expect(std::bind(weak_fn(&T::fri, p))() == 2);
+ expect(called);
+ }
+
+ {
+ bool called = false;
+ auto p = std::make_shared(called);
+ auto call = std::bind(weak_fn(&T::fv, p,
+ [&called]()
+ {
+ called = true;
+ }));
+ p.reset();
+ call();
+ expect(called);
+ }
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(weak_fn,asio,beast);
+
+}
diff --git a/src/beast/beast/weak_fn.h b/src/beast/beast/weak_fn.h
new file mode 100644
index 000000000..67eb335d0
--- /dev/null
+++ b/src/beast/beast/weak_fn.h
@@ -0,0 +1,175 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2014, Vinnie Falco
+
+ 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.
+*/
+//==============================================================================
+
+#ifndef BEAST_WEAK_FN_H_INCLUDED
+#define BEAST_WEAK_FN_H_INCLUDED
+
+#include
+#include
+
+// Original version:
+// http://lists.boost.org/Archives/boost/att-189469/weak_fn.hpp
+//
+// This work was adapted from source code with this copyright notice:
+//
+// weak_fun.hpp
+//
+// Copyright (c) 2009 Artyom Beilis
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+namespace beast {
+
+// Policy throws if weak pointer is expired
+template
+struct throw_if_invalid
+{
+ V operator()() const
+ {
+ throw std::bad_weak_ptr();
+ }
+};
+
+// Policy returns a value if weak pointer is expired
+template
+struct return_default_if_invalid
+{
+ return_default_if_invalid()
+ : def_value_()
+ { }
+
+ return_default_if_invalid(V def_value)
+ : def_value_(def_value)
+ { }
+
+ V operator()() const
+ {
+ return def_value_;
+ }
+
+private:
+ V def_value_;
+};
+
+// Policy does nothing if weak pointer is expired
+template
+struct ignore_if_invalid
+{
+ V operator()() const
+ {
+ return V();
+ }
+};
+
+template
+using default_invalid_policy = ignore_if_invalid;
+
+namespace detail {
+
+template
+class weak_binder
+ : private beast::empty_base_optimization
+{
+private:
+ typedef R (T::*member_type)(Args...);
+ using pointer_type = std::weak_ptr;
+ using shared_type = std::shared_ptr;
+ member_type member_;
+ pointer_type object_;
+
+public:
+ using result_type = R;
+
+ weak_binder (member_type member,
+ Policy policy, pointer_type object)
+ : empty_base_optimization(std::move(policy))
+ , member_(member)
+ , object_(object)
+ { }
+
+ R operator()(Args... args)
+ {
+ if(auto p = object_.lock())
+ return ((*p).*member_)(args...);
+ return this->member()();
+ }
+};
+
+} // detail
+
+/** Returns a callback that can be used with std::bind and a weak_ptr.
+ When called, it tries to lock weak_ptr to get a shared_ptr. If successful,
+ it calls given member function with given arguments. If not successful,
+ the policy functor is called. Built-in policies are:
+
+ ignore_if_invalid does nothing
+ throw_if_invalid throws `bad_weak_ptr`
+ return_default_if_invalid returns a chosen value
+
+ Example:
+
+ struct Foo {
+ void bar(int i) {
+ std::cout << i << std::endl;
+ }
+ };
+
+ struct do_something {
+ void operator()() {
+ std::cout << "outdated reference" << std::endl;
+ }
+ };
+
+ int main()
+ {
+ std::shared_ptr sp(new Foo());
+ std::weak_ptr wp(sp);
+
+ std::bind(weak_fn(&Foo::bar, wp), _1)(1);
+ sp.reset();
+ std::bind(weak_fn(&Foo::bar, wp), 1)();
+ std::bind(weak_fn(&Foo::bar, wp, do_something()), 1)();
+ }
+*/
+/** @{ */
+template
+detail::weak_binder
+weak_fn (R (T::*member)(Args...), std::shared_ptr p,
+ Policy policy)
+{
+ return detail::weak_binder(member, policy, p);
+}
+
+template
+detail::weak_binder, Args...>
+weak_fn (R (T::*member)(Args...), std::shared_ptr p)
+{
+ return detail::weak_binder, Args...>(member,
+ default_invalid_policy{}, p);
+}
+/** @} */
+
+} // beast
+
+#endif