diff options
| author | Andre Heinecke <[email protected]> | 2016-04-03 12:46:51 +0000 | 
|---|---|---|
| committer | Andre Heinecke <[email protected]> | 2016-04-03 12:46:51 +0000 | 
| commit | c07aaef6eb8a9b5e623479f27d562fd1570bf4bb (patch) | |
| tree | db5fac0d76418019f11ffe9a9f4e5e2e7658b872 | |
| parent | Qt: Add static factor methods for protocol (diff) | |
| download | gpgme-c07aaef6eb8a9b5e623479f27d562fd1570bf4bb.tar.gz gpgme-c07aaef6eb8a9b5e623479f27d562fd1570bf4bb.zip | |
Cpp: Require c++ 11 if cpp binding requested
* configure.ac: Call ax_cxx_compile_stdcxx
* m4/ax_cxx_compile_stdcxx.m4
--
Depending on c++11 is intended to make the port away from
Boost easier.
The m4 macro was taken from the website mentioned in the License
header of the file.
Diffstat (limited to '')
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | m4/ax_cxx_compile_stdcxx.m4 | 562 | 
2 files changed, 568 insertions, 0 deletions
| diff --git a/configure.ac b/configure.ac index 8580be7b..b6b67ef3 100644 --- a/configure.ac +++ b/configure.ac @@ -266,6 +266,12 @@ for language in $enabled_languages; do         AC_MSG_ERROR([unsupported language binding specified])      fi  done +# Enable C++ 11 if cpp language is requested +LIST_MEMBER("cpp", $enabled_languages) +if test "$found" = "1"; then +    AX_CXX_COMPILE_STDCXX(11, noext, optional) +fi +  # Check that if qt is enabled cpp also is enabled  LIST_MEMBER("qt", $enabled_languages)  if test "$found" = "1"; then diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 00000000..2c18e49c --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,562 @@ +# =========================================================================== +#   http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +#   Check for baseline language coverage in the compiler for the specified +#   version of the C++ standard.  If necessary, add switches to CXX and +#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard) +#   or '14' (for the C++14 standard). +# +#   The second argument, if specified, indicates whether you insist on an +#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +#   -std=c++11).  If neither is specified, you get whatever works, with +#   preference for an extended mode. +# +#   The third argument, if specified 'mandatory' or if left unspecified, +#   indicates that baseline support for the specified C++ standard is +#   required and that the macro should error out if no mode with that +#   support is found.  If specified 'optional', then configuration proceeds +#   regardless, after defining HAVE_CXX${VERSION} if and only if a +#   supporting mode is found. +# +# LICENSE +# +#   Copyright (c) 2008 Benjamin Kosnik <[email protected]> +#   Copyright (c) 2012 Zack Weinberg <[email protected]> +#   Copyright (c) 2013 Roy Stogner <[email protected]> +#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <[email protected]> +#   Copyright (c) 2015 Paul Norman <[email protected]> +#   Copyright (c) 2015 Moritz Klammler <[email protected]> +# +#   Copying and distribution of this file, with or without modification, are +#   permitted in any medium without royalty provided the copyright notice +#   and this notice are preserved.  This file is offered as-is, without any +#   warranty. + +#serial 4 + +dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl  (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl +  m4_if([$1], [11], [], +        [$1], [14], [], +        [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], +        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl +  m4_if([$2], [], [], +        [$2], [ext], [], +        [$2], [noext], [], +        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl +  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], +        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], +        [$3], [optional], [ax_cxx_compile_cxx$1_required=false], +        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) +  AC_LANG_PUSH([C++])dnl +  ac_success=no +  AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, +  ax_cv_cxx_compile_cxx$1, +  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], +    [ax_cv_cxx_compile_cxx$1=yes], +    [ax_cv_cxx_compile_cxx$1=no])]) +  if test x$ax_cv_cxx_compile_cxx$1 = xyes; then +    ac_success=yes +  fi + +  m4_if([$2], [noext], [], [dnl +  if test x$ac_success = xno; then +    for switch in -std=gnu++$1 -std=gnu++0x; do +      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) +      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, +                     $cachevar, +        [ac_save_CXX="$CXX" +         CXX="$CXX $switch" +         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], +          [eval $cachevar=yes], +          [eval $cachevar=no]) +         CXX="$ac_save_CXX"]) +      if eval test x\$$cachevar = xyes; then +        CXX="$CXX $switch" +        if test -n "$CXXCPP" ; then +          CXXCPP="$CXXCPP $switch" +        fi +        ac_success=yes +        break +      fi +    done +  fi]) + +  m4_if([$2], [ext], [], [dnl +  if test x$ac_success = xno; then +    dnl HP's aCC needs +std=c++11 according to: +    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf +    dnl Cray's crayCC needs "-h std=c++11" +    for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do +      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) +      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, +                     $cachevar, +        [ac_save_CXX="$CXX" +         CXX="$CXX $switch" +         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], +          [eval $cachevar=yes], +          [eval $cachevar=no]) +         CXX="$ac_save_CXX"]) +      if eval test x\$$cachevar = xyes; then +        CXX="$CXX $switch" +        if test -n "$CXXCPP" ; then +          CXXCPP="$CXXCPP $switch" +        fi +        ac_success=yes +        break +      fi +    done +  fi]) +  AC_LANG_POP([C++]) +  if test x$ax_cxx_compile_cxx$1_required = xtrue; then +    if test x$ac_success = xno; then +      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) +    fi +  fi +  if test x$ac_success = xno; then +    HAVE_CXX$1=0 +    AC_MSG_NOTICE([No compiler with C++$1 support was found]) +  else +    HAVE_CXX$1=1 +    AC_DEFINE(HAVE_CXX$1,1, +              [define if the compiler supports basic C++$1 syntax]) +  fi +  AC_SUBST(HAVE_CXX$1) +]) + + +dnl  Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl  Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + + +dnl  Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + +  namespace test_static_assert +  { + +    template <typename T> +    struct check +    { +      static_assert(sizeof(int) <= sizeof(T), "not big enough"); +    }; + +  } + +  namespace test_final_override +  { + +    struct Base +    { +      virtual void f() {} +    }; + +    struct Derived : public Base +    { +      virtual void f() override {} +    }; + +  } + +  namespace test_double_right_angle_brackets +  { + +    template < typename T > +    struct check {}; + +    typedef check<void> single_type; +    typedef check<check<void>> double_type; +    typedef check<check<check<void>>> triple_type; +    typedef check<check<check<check<void>>>> quadruple_type; + +  } + +  namespace test_decltype +  { + +    int +    f() +    { +      int a = 1; +      decltype(a) b = 2; +      return a + b; +    } + +  } + +  namespace test_type_deduction +  { + +    template < typename T1, typename T2 > +    struct is_same +    { +      static const bool value = false; +    }; + +    template < typename T > +    struct is_same<T, T> +    { +      static const bool value = true; +    }; + +    template < typename T1, typename T2 > +    auto +    add(T1 a1, T2 a2) -> decltype(a1 + a2) +    { +      return a1 + a2; +    } + +    int +    test(const int c, volatile int v) +    { +      static_assert(is_same<int, decltype(0)>::value == true, ""); +      static_assert(is_same<int, decltype(c)>::value == false, ""); +      static_assert(is_same<int, decltype(v)>::value == false, ""); +      auto ac = c; +      auto av = v; +      auto sumi = ac + av + 'x'; +      auto sumf = ac + av + 1.0; +      static_assert(is_same<int, decltype(ac)>::value == true, ""); +      static_assert(is_same<int, decltype(av)>::value == true, ""); +      static_assert(is_same<int, decltype(sumi)>::value == true, ""); +      static_assert(is_same<int, decltype(sumf)>::value == false, ""); +      static_assert(is_same<int, decltype(add(c, v))>::value == true, ""); +      return (sumf > 0.0) ? sumi : add(c, v); +    } + +  } + +  namespace test_noexcept +  { + +    int f() { return 0; } +    int g() noexcept { return 0; } + +    static_assert(noexcept(f()) == false, ""); +    static_assert(noexcept(g()) == true, ""); + +  } + +  namespace test_constexpr +  { + +    template < typename CharT > +    unsigned long constexpr +    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept +    { +      return *s ? strlen_c_r(s + 1, acc + 1) : acc; +    } + +    template < typename CharT > +    unsigned long constexpr +    strlen_c(const CharT *const s) noexcept +    { +      return strlen_c_r(s, 0UL); +    } + +    static_assert(strlen_c("") == 0UL, ""); +    static_assert(strlen_c("1") == 1UL, ""); +    static_assert(strlen_c("example") == 7UL, ""); +    static_assert(strlen_c("another\0example") == 7UL, ""); + +  } + +  namespace test_rvalue_references +  { + +    template < int N > +    struct answer +    { +      static constexpr int value = N; +    }; + +    answer<1> f(int&)       { return answer<1>(); } +    answer<2> f(const int&) { return answer<2>(); } +    answer<3> f(int&&)      { return answer<3>(); } + +    void +    test() +    { +      int i = 0; +      const int c = 0; +      static_assert(decltype(f(i))::value == 1, ""); +      static_assert(decltype(f(c))::value == 2, ""); +      static_assert(decltype(f(0))::value == 3, ""); +    } + +  } + +  namespace test_uniform_initialization +  { + +    struct test +    { +      static const int zero {}; +      static const int one {1}; +    }; + +    static_assert(test::zero == 0, ""); +    static_assert(test::one == 1, ""); + +  } + +  namespace test_lambdas +  { + +    void +    test1() +    { +      auto lambda1 = [](){}; +      auto lambda2 = lambda1; +      lambda1(); +      lambda2(); +    } + +    int +    test2() +    { +      auto a = [](int i, int j){ return i + j; }(1, 2); +      auto b = []() -> int { return '0'; }(); +      auto c = [=](){ return a + b; }(); +      auto d = [&](){ return c; }(); +      auto e = [a, &b](int x) mutable { +        const auto identity = [](int y){ return y; }; +        for (auto i = 0; i < a; ++i) +          a += b--; +        return x + identity(a + b); +      }(0); +      return a + b + c + d + e; +    } + +    int +    test3() +    { +      const auto nullary = [](){ return 0; }; +      const auto unary = [](int x){ return x; }; +      using nullary_t = decltype(nullary); +      using unary_t = decltype(unary); +      const auto higher1st = [](nullary_t f){ return f(); }; +      const auto higher2nd = [unary](nullary_t f1){ +        return [unary, f1](unary_t f2){ return f2(unary(f1())); }; +      }; +      return higher1st(nullary) + higher2nd(nullary)(unary); +    } + +  } + +  namespace test_variadic_templates +  { + +    template <int...> +    struct sum; + +    template <int N0, int... N1toN> +    struct sum<N0, N1toN...> +    { +      static constexpr auto value = N0 + sum<N1toN...>::value; +    }; + +    template <> +    struct sum<> +    { +      static constexpr auto value = 0; +    }; + +    static_assert(sum<>::value == 0, ""); +    static_assert(sum<1>::value == 1, ""); +    static_assert(sum<23>::value == 23, ""); +    static_assert(sum<1, 2>::value == 3, ""); +    static_assert(sum<5, 5, 11>::value == 21, ""); +    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + +  } + +  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae +  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function +  // because of this. +  namespace test_template_alias_sfinae +  { + +    struct foo {}; + +    template<typename T> +    using member = typename T::member_type; + +    template<typename T> +    void func(...) {} + +    template<typename T> +    void func(member<T>*) {} + +    void test(); + +    void test() { func<foo>(0); } + +  } + +}  // namespace cxx11 + +#endif  // __cplusplus >= 201103L + +]]) + + +dnl  Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + +  namespace test_polymorphic_lambdas +  { + +    int +    test() +    { +      const auto lambda = [](auto&&... args){ +        const auto istiny = [](auto x){ +          return (sizeof(x) == 1UL) ? 1 : 0; +        }; +        const int aretiny[] = { istiny(args)... }; +        return aretiny[0]; +      }; +      return lambda(1, 1L, 1.0f, '1'); +    } + +  } + +  namespace test_binary_literals +  { + +    constexpr auto ivii = 0b0000000000101010; +    static_assert(ivii == 42, "wrong value"); + +  } + +  namespace test_generalized_constexpr +  { + +    template < typename CharT > +    constexpr unsigned long +    strlen_c(const CharT *const s) noexcept +    { +      auto length = 0UL; +      for (auto p = s; *p; ++p) +        ++length; +      return length; +    } + +    static_assert(strlen_c("") == 0UL, ""); +    static_assert(strlen_c("x") == 1UL, ""); +    static_assert(strlen_c("test") == 4UL, ""); +    static_assert(strlen_c("another\0test") == 7UL, ""); + +  } + +  namespace test_lambda_init_capture +  { + +    int +    test() +    { +      auto x = 0; +      const auto lambda1 = [a = x](int b){ return a + b; }; +      const auto lambda2 = [a = lambda1(x)](){ return a; }; +      return lambda2(); +    } + +  } + +  namespace test_digit_seperators +  { + +    constexpr auto ten_million = 100'000'000; +    static_assert(ten_million == 100000000, ""); + +  } + +  namespace test_return_type_deduction +  { + +    auto f(int& x) { return x; } +    decltype(auto) g(int& x) { return x; } + +    template < typename T1, typename T2 > +    struct is_same +    { +      static constexpr auto value = false; +    }; + +    template < typename T > +    struct is_same<T, T> +    { +      static constexpr auto value = true; +    }; + +    int +    test() +    { +      auto x = 0; +      static_assert(is_same<int, decltype(f(x))>::value, ""); +      static_assert(is_same<int&, decltype(g(x))>::value, ""); +      return x; +    } + +  } + +}  // namespace cxx14 + +#endif  // __cplusplus >= 201402L + +]]) | 
