| 1 | # HG changeset patch |
| 2 | # User Kefu Chai <tchaikov@gmail.com> |
| 3 | # Date 1413043255 -28800 |
| 4 | # Sun Oct 12 00:00:55 2014 +0800 |
| 5 | # Node ID 1433cd4f7b7bda0b0e0a04f990b55ffc3cbaf701 |
| 6 | # Parent 91a6f06c505220d269de3a0dab8cc898d03d91a0 |
| 7 | fix the build error on clang 3.5 and libc++ (bug #43298) |
| 8 | |
| 9 | * liboctave/operators/mx-inlines.cc: |
| 10 | use the workaround if libc++ with this issue is detected. |
| 11 | |
| 12 | * liboctave/operators/libcxx-fix.cc: |
| 13 | add a workaround for http://llvm.org/bugs/show_bug.cgi?id=21083, so that only |
| 14 | the arithmetic types are accepted for the function template "libcxx_fix::pow()". |
| 15 | |
| 16 | diff -r 91a6f06c5052 -r 1433cd4f7b7b liboctave/operators/libcxx-fix.h |
| 17 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
| 18 | +++ liboctave/operators/libcxx-fix.h Sun Oct 12 00:00:55 2014 +0800 |
| 19 | @@ -0,0 +1,69 @@ |
| 20 | +#ifndef _LIBCPP_VERSION |
| 21 | +#error "for libc++ only" |
| 22 | +#endif |
| 23 | + |
| 24 | +namespace libcxx_fix { |
| 25 | + |
| 26 | +using std::is_integral; |
| 27 | +using std::is_same; |
| 28 | +using std::enable_if; |
| 29 | + |
| 30 | +template <class _Tp, class _Tn = void> |
| 31 | +struct numeric_type |
| 32 | +{ |
| 33 | + typedef void type; |
| 34 | + static const bool value = false; |
| 35 | +}; |
| 36 | + |
| 37 | +template <class _Tp> |
| 38 | +struct numeric_type<_Tp, typename enable_if<is_integral<_Tp>::value || |
| 39 | + is_same<_Tp, double>::value>::type> |
| 40 | +{ |
| 41 | + typedef double type; |
| 42 | + static const bool value = true; |
| 43 | +}; |
| 44 | + |
| 45 | +template <class _Tp> |
| 46 | +struct numeric_type<_Tp, typename enable_if<is_same<_Tp, long double>::value || |
| 47 | + is_same<_Tp, float>::value>::type> |
| 48 | +{ |
| 49 | + typedef _Tp type; |
| 50 | + static const bool value = true; |
| 51 | +}; |
| 52 | + |
| 53 | +template <> |
| 54 | +struct numeric_type<void, void> |
| 55 | +{ |
| 56 | + static const bool value = true; |
| 57 | +}; |
| 58 | + |
| 59 | +template <class _A1, class _A2, |
| 60 | + bool = numeric_type<_A1>::value && |
| 61 | + numeric_type<_A2>::value> |
| 62 | +class promote |
| 63 | +{}; |
| 64 | + |
| 65 | +template <class _A1, class _A2> |
| 66 | +class promote<_A1, _A2, true> |
| 67 | +{ |
| 68 | +private: |
| 69 | + typedef typename numeric_type<_A1>::type __type1; |
| 70 | + typedef typename numeric_type<_A2>::type __type2; |
| 71 | +public: |
| 72 | + typedef decltype(__type1() + __type2()) type; |
| 73 | +}; |
| 74 | + |
| 75 | +template <class _A1, class _A2> |
| 76 | +inline _LIBCPP_INLINE_VISIBILITY |
| 77 | +typename promote<_A1, _A2>::type |
| 78 | +pow(_A1 __x, _A2 __y) _NOEXCEPT |
| 79 | +{ |
| 80 | + typedef typename promote<_A1, _A2>::type __result_type; |
| 81 | +#if _LIBCPP_STD_VER > 11 |
| 82 | + static_assert((!(is_same<_A1, __result_type>::value && |
| 83 | + is_same<_A2, __result_type>::value)), ""); |
| 84 | +#endif |
| 85 | + return ::pow(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); |
| 86 | +} |
| 87 | + |
| 88 | +} |
| 89 | diff -r 91a6f06c5052 -r 1433cd4f7b7b liboctave/operators/mx-inlines.cc |
| 90 | --- liboctave/operators/mx-inlines.cc Thu Oct 09 20:38:04 2014 -0700 |
| 91 | +++ liboctave/operators/mx-inlines.cc Sun Oct 12 00:00:55 2014 +0800 |
| 92 | @@ -306,7 +306,13 @@ |
| 93 | |
| 94 | // Let the compiler decide which pow to use, whichever best matches the |
| 95 | // arguments provided. |
| 96 | +#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 1101) |
| 97 | +// Workaround http://llvm.org/bugs/show_bug.cgi?id=21083 |
| 98 | +#include "libcxx-fix.h" |
| 99 | +using libcxx_fix::pow; |
| 100 | +#else |
| 101 | using std::pow; |
| 102 | +#endif |
| 103 | DEFMXMAPPER2X (mx_inline_pow, pow) |
| 104 | |
| 105 | // Arbitrary function appliers. The function is a template parameter to enable |