From e540d7fdd346179323e99e11e3d350b18d3758f7 Mon Sep 17 00:00:00 2001
From: Daniel Hartwig <mandyke@gmail.com>
Date: Fri, 31 May 2013 10:53:16 +0800
Subject: [PATCH] support again Boost < 1.53

* configure.ac: Determine the return type of boost::make_shared.
* src/generic/util/sqlite.h: Use that information.
---
 configure.ac              |   55 +++++++++++++++++++++++++++++++++++++++++++++
 src/generic/util/sqlite.h |   10 +++++++++
 2 files changed, 65 insertions(+)

diff --git a/configure.ac b/configure.ac
index f582f43..5e00ec6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -494,6 +494,61 @@ AC_SUBST(BOOST_UNIT_TEST_LIBS)
 
 ##### End Boost.Test check #####
 
+dnl Boost 1.53 introduced indirection to the return type of
+dnl make_shared that interferes with befriending it.  This is strange
+dnl as the effective return type does not change, so maybe I missed
+dnl another way to support this.
+
+AC_MSG_CHECKING([the return type of boost::make_shared])
+boost_make_shared_return_type=no
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+class Foo
+{
+  template< typename T, typename A >
+  friend boost::shared_ptr< T >
+    boost::make_shared(const A &);
+  private:
+  Foo(int a) {}
+};
+
+int main(int argc, char *argv[])
+{
+  boost::shared_ptr< Foo > x = boost::make_shared< Foo >(1);
+}
+                  ])],
+                  [AC_DEFINE([BOOST_MAKE_SHARED_SHARED_PTR], [1],
+                             [Define if boost::make_shared returns shared_pointer directly.])
+                   boost_make_shared_return_type="boost::shared_ptr< T >"])
+if test "$boost_make_shared_return_type" = "no"; then
+  AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+class Foo
+{
+  template< typename T, typename A >
+  friend typename boost::detail::sp_if_not_array< T >::type
+    boost::make_shared(const A &);
+  private:
+  Foo(int a) {}
+};
+
+int main(int argc, char *argv[])
+{
+  boost::shared_ptr< Foo > x = boost::make_shared< Foo >(1);
+}
+                  ])],
+                  [AC_DEFINE([BOOST_MAKE_SHARED_SP_IF_NOT_ARRAY_TYPE], [1],
+                             [Define if boost::make_shared returns sp_if_not_array::type.])
+                   boost_make_shared_return_type="typename boost::detail::sp_if_not_array< T >::type"])
+fi
+if test "$boost_make_shared_return_type" = "no"; then
+  AC_MSG_FAILURE([unknown])
+else
+  AC_MSG_RESULT([$boost_make_shared_return_type])
+fi
+
 ##### Check for Google Mock #####
 
 dnl Google Mock's developers do not support prebuilt libraries (e.g.,
diff --git a/src/generic/util/sqlite.h b/src/generic/util/sqlite.h
index 253d9ad..3f13110 100644
--- a/src/generic/util/sqlite.h
+++ b/src/generic/util/sqlite.h
@@ -20,6 +20,10 @@
 #ifndef SQLITE_H
 #define SQLITE_H
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <cwidget/generic/threads/threads.h>
 #include <cwidget/generic/util/exception.h>
 
@@ -372,12 +376,15 @@ namespace aptitude
       friend class db::statement_proxy_impl;
 
       statement(db &_parent, sqlite3_stmt *_handle);
+#if defined(BOOST_MAKE_SHARED_SHARED_PTR)
       template<typename A, typename B, typename C>
       friend boost::shared_ptr<A> boost::make_shared(const B &, const C &);
+#elif defined(BOOST_MAKE_SHARED_SP_IF_NOT_ARRAY_TYPE)
       // FIXME: Ouch.  Boost 1.53 requires this mess or something else
       // I haven't worked out yet.
       template<typename A, typename B, typename C>
       friend typename boost::detail::sp_if_not_array<A>::type boost::make_shared(const B &, const C &);
+#endif
 
       /** \brief Throw an exception if there isn't result data ready
        *  to be read.
@@ -569,11 +576,14 @@ namespace aptitude
       friend class db;
 
       blob(db &_parent, sqlite3_blob *_handle);
+#if defined(BOOST_MAKE_SHARED_SHARED_PTR)
       template<typename A, typename B, typename C>
       friend boost::shared_ptr<A> boost::make_shared(const B &, const C &);
+#elif defined(BOOST_MAKE_SHARED_SP_IF_NOT_ARRAY_TYPE)
       // FIXME: Ouch.  Again.
       template<typename A, typename B, typename C>
       friend typename boost::detail::sp_if_not_array<A>::type boost::make_shared(const B &, const C &);
+#endif
 
     public:
       /** \brief Open an existing BLOB.
-- 
1.7.10.4

