# HG changeset patch
# User Kefu Chai <tchaikov@gmail.com>
# Date 1414900607 -28800
#      Sun Nov 02 11:56:47 2014 +0800
# Branch gui-release
# Node ID cfeca0c9d02f56a20bd757015a000cfc04967ace
# Parent  82c329619836d0e7e3e491a7c52f2aeebc6679c3
fix the build error on clang 3.5 and libc++ (bug #43298)

* liboctave/operators/mx-inlines.cc:
use the workaround if libc++ with this issue is detected.

* liboctave/operators/libcxx-fix.h:
add a workaround for http://llvm.org/bugs/show_bug.cgi?id=21083, so that only
the arithmetic types are accepted for the function template "libcxx_fix::pow()".

* liboctave/operators/module.mk:
ship the libcxx-fix.h as well

* liboctave/Makefile.in:
XXX: update the generated Makefile.in, as downstream might be using a different
automake version from the one upstream is using.

diff -r 82c329619836 -r cfeca0c9d02f liboctave/operators/libcxx-fix.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/operators/libcxx-fix.h	Sun Nov 02 11:56:47 2014 +0800
@@ -0,0 +1,69 @@
+#ifndef _LIBCPP_VERSION
+#error "for libc++ only"
+#endif
+
+namespace libcxx_fix {
+
+using std::is_integral;
+using std::is_same;
+using std::enable_if;
+
+template <class _Tp, class _Tn = void>
+struct numeric_type
+{
+    typedef void type;
+    static const bool value = false;
+};
+
+template <class _Tp>
+struct numeric_type<_Tp, typename enable_if<is_integral<_Tp>::value ||
+                                            is_same<_Tp, double>::value>::type>
+{
+    typedef double type;
+    static const bool value = true;
+};
+
+template <class _Tp>
+struct numeric_type<_Tp, typename enable_if<is_same<_Tp, long double>::value ||
+                                            is_same<_Tp, float>::value>::type>
+{
+    typedef _Tp type;
+    static const bool value = true;
+};
+
+template <>
+struct numeric_type<void, void>
+{
+    static const bool value = true;
+};
+
+template <class _A1, class _A2,
+          bool = numeric_type<_A1>::value &&
+                 numeric_type<_A2>::value>
+class promote
+{};
+
+template <class _A1, class _A2>
+class promote<_A1, _A2, true>
+{
+private:
+    typedef typename numeric_type<_A1>::type __type1;
+    typedef typename numeric_type<_A2>::type __type2;
+public:
+    typedef decltype(__type1() + __type2()) type;
+};
+
+template <class _A1, class _A2>
+inline _LIBCPP_INLINE_VISIBILITY
+typename promote<_A1, _A2>::type
+pow(_A1 __x, _A2 __y) _NOEXCEPT
+{
+    typedef typename promote<_A1, _A2>::type __result_type;
+#if _LIBCPP_STD_VER > 11
+    static_assert((!(is_same<_A1, __result_type>::value &&
+                     is_same<_A2, __result_type>::value)), "");
+#endif
+    return ::pow(static_cast<__result_type>(__x), static_cast<__result_type>(__y));
+}
+
+}
diff -r 82c329619836 -r cfeca0c9d02f liboctave/operators/module.mk
--- a/liboctave/operators/module.mk	Wed Oct 15 11:01:00 2014 -0400
+++ b/liboctave/operators/module.mk	Sun Nov 02 11:56:47 2014 +0800
@@ -34,7 +34,8 @@
   operators/mx-op-defs.h \
   operators/Sparse-diag-op-defs.h \
   operators/Sparse-op-defs.h \
-  operators/Sparse-perm-op-defs.h
+  operators/Sparse-perm-op-defs.h \
+  operators/libcxx-fix.h
 
 ## There are no distributed source files in this directory
 OPERATORS_SRC =
diff -r 82c329619836 -r cfeca0c9d02f liboctave/Makefile.in
--- a/liboctave/Makefile.in	Wed Oct 15 11:01:00 2014 -0400
+++ b/liboctave/Makefile.in	Sun Nov 02 11:57:13 2014 +0800
@@ -3188,7 +3188,8 @@
   operators/mx-op-defs.h \
   operators/Sparse-diag-op-defs.h \
   operators/Sparse-op-defs.h \
-  operators/Sparse-perm-op-defs.h
+  operators/Sparse-perm-op-defs.h \
+  operators/libcxx-fix.h

 OPERATORS_SRC =
 OP_SRCDIR = $(abs_top_srcdir)/liboctave/operators
diff -r 82c329619836 -r cfeca0c9d02f liboctave/operators/mx-inlines.cc
--- a/liboctave/operators/mx-inlines.cc	Wed Oct 15 11:01:00 2014 -0400
+++ b/liboctave/operators/mx-inlines.cc	Sun Nov 02 11:56:47 2014 +0800
@@ -306,7 +306,13 @@
 
 // Let the compiler decide which pow to use, whichever best matches the
 // arguments provided.
+#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 1101)
+// Workaround http://llvm.org/bugs/show_bug.cgi?id=21083
+#include "libcxx-fix.h"
+using libcxx_fix::pow;
+#else
 using std::pow;
+#endif
 DEFMXMAPPER2X (mx_inline_pow, pow)
 
 // Arbitrary function appliers. The function is a template parameter to enable
