Project

General

Profile

Bug #1270 » cpp11-autoconf.diff

autoconf changes - Ben Touchette, 17 Feb 2017 18:02

View differences:

trunk/config/aclocal.m4 (revision 4698) → trunk/config/aclocal.m4 (working copy)
10198 10198
    $5
10199 10199
  ])
10200 10200
])
10201
# ===========================================================================
10202
#   http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
10203
# ===========================================================================
10204
#
10205
# SYNOPSIS
10206
#
10207
#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
10208
#
10209
# DESCRIPTION
10210
#
10211
#   Check for baseline language coverage in the compiler for the specified
10212
#   version of the C++ standard.  If necessary, add switches to CXX and
10213
#   CXXCPP to enable support.  VERSION may be '11' (for the C++11 standard)
10214
#   or '14' (for the C++14 standard).
10215
#
10216
#   The second argument, if specified, indicates whether you insist on an
10217
#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
10218
#   -std=c++11).  If neither is specified, you get whatever works, with
10219
#   preference for an extended mode.
10220
#
10221
#   The third argument, if specified 'mandatory' or if left unspecified,
10222
#   indicates that baseline support for the specified C++ standard is
10223
#   required and that the macro should error out if no mode with that
10224
#   support is found.  If specified 'optional', then configuration proceeds
10225
#   regardless, after defining HAVE_CXX${VERSION} if and only if a
10226
#   supporting mode is found.
10227
#
10228
# LICENSE
10229
#
10230
#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
10231
#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
10232
#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
10233
#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
10234
#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
10235
#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
10236
#   Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
10237
#
10238
#   Copying and distribution of this file, with or without modification, are
10239
#   permitted in any medium without royalty provided the copyright notice
10240
#   and this notice are preserved.  This file is offered as-is, without any
10241
#   warranty.
10242

  
10243
#serial 6
10244

  
10245
dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
10246
dnl  (serial version number 13).
10247

  
10248
AX_REQUIRE_DEFINED([AC_MSG_WARN])
10249
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
10250
  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
10251
        [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
10252
        [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
10253
        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
10254
  m4_if([$2], [], [],
10255
        [$2], [ext], [],
10256
        [$2], [noext], [],
10257
        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
10258
  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
10259
        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
10260
        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
10261
        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
10262
  AC_LANG_PUSH([C++])dnl
10263
  ac_success=no
10264
  AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
10265
  ax_cv_cxx_compile_cxx$1,
10266
  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
10267
    [ax_cv_cxx_compile_cxx$1=yes],
10268
    [ax_cv_cxx_compile_cxx$1=no])])
10269
  if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
10270
    ac_success=yes
10271
  fi
10272

  
10273
  m4_if([$2], [noext], [], [dnl
10274
  if test x$ac_success = xno; then
10275
    for alternative in ${ax_cxx_compile_alternatives}; do
10276
      switch="-std=gnu++${alternative}"
10277
      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
10278
      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
10279
                     $cachevar,
10280
        [ac_save_CXX="$CXX"
10281
         CXX="$CXX $switch"
10282
         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
10283
          [eval $cachevar=yes],
10284
          [eval $cachevar=no])
10285
         CXX="$ac_save_CXX"])
10286
      if eval test x\$$cachevar = xyes; then
10287
        CXX="$CXX $switch"
10288
        if test -n "$CXXCPP" ; then
10289
          CXXCPP="$CXXCPP $switch"
10290
        fi
10291
        ac_success=yes
10292
        break
10293
      fi
10294
    done
10295
  fi])
10296

  
10297
  m4_if([$2], [ext], [], [dnl
10298
  if test x$ac_success = xno; then
10299
    dnl HP's aCC needs +std=c++11 according to:
10300
    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
10301
    dnl Cray's crayCC needs "-h std=c++11"
10302
    for alternative in ${ax_cxx_compile_alternatives}; do
10303
      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
10304
        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
10305
        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
10306
                       $cachevar,
10307
          [ac_save_CXX="$CXX"
10308
           CXX="$CXX $switch"
10309
           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
10310
            [eval $cachevar=yes],
10311
            [eval $cachevar=no])
10312
           CXX="$ac_save_CXX"])
10313
        if eval test x\$$cachevar = xyes; then
10314
          CXX="$CXX $switch"
10315
          if test -n "$CXXCPP" ; then
10316
            CXXCPP="$CXXCPP $switch"
10317
          fi
10318
          ac_success=yes
10319
          break
10320
        fi
10321
      done
10322
      if test x$ac_success = xyes; then
10323
        break
10324
      fi
10325
    done
10326
  fi])
10327
  AC_LANG_POP([C++])
10328
  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
10329
    if test x$ac_success = xno; then
10330
      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
10331
    fi
10332
  fi
10333
  if test x$ac_success = xno; then
10334
    HAVE_CXX$1=0
10335
    AC_MSG_NOTICE([No compiler with C++$1 support was found])
10336
  else
10337
    HAVE_CXX$1=1
10338
    AC_DEFINE(HAVE_CXX$1,1,
10339
              [define if the compiler supports basic C++$1 syntax])
10340
  fi
10341
  AC_SUBST(HAVE_CXX$1)
10342
  m4_if([$1], [17], [AC_MSG_WARN([C++17 is not yet standardized, so the checks may change in incompatible ways anytime])])
10343
])
10344

  
10345

  
10346
dnl  Test body for checking C++11 support
10347

  
10348
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
10349
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
10350
)
10351

  
10352

  
10353
dnl  Test body for checking C++14 support
10354

  
10355
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
10356
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
10357
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
10358
)
10359

  
10360
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
10361
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
10362
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
10363
  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
10364
)
10365

  
10366
dnl  Tests for new features in C++11
10367

  
10368
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
10369

  
10370
// If the compiler admits that it is not ready for C++11, why torture it?
10371
// Hopefully, this will speed up the test.
10372

  
10373
#ifndef __cplusplus
10374

  
10375
#error "This is not a C++ compiler"
10376

  
10377
#elif __cplusplus < 201103L
10378

  
10379
#error "This is not a C++11 compiler"
10380

  
10381
#else
10382

  
10383
namespace cxx11
10384
{
10385

  
10386
  namespace test_static_assert
10387
  {
10388

  
10389
    template <typename T>
10390
    struct check
10391
    {
10392
      static_assert(sizeof(int) <= sizeof(T), "not big enough");
10393
    };
10394

  
10395
  }
10396

  
10397
  namespace test_final_override
10398
  {
10399

  
10400
    struct Base
10401
    {
10402
      virtual void f() {}
10403
    };
10404

  
10405
    struct Derived : public Base
10406
    {
10407
      virtual void f() override {}
10408
    };
10409

  
10410
  }
10411

  
10412
  namespace test_double_right_angle_brackets
10413
  {
10414

  
10415
    template < typename T >
10416
    struct check {};
10417

  
10418
    typedef check<void> single_type;
10419
    typedef check<check<void>> double_type;
10420
    typedef check<check<check<void>>> triple_type;
10421
    typedef check<check<check<check<void>>>> quadruple_type;
10422

  
10423
  }
10424

  
10425
  namespace test_decltype
10426
  {
10427

  
10428
    int
10429
    f()
10430
    {
10431
      int a = 1;
10432
      decltype(a) b = 2;
10433
      return a + b;
10434
    }
10435

  
10436
  }
10437

  
10438
  namespace test_type_deduction
10439
  {
10440

  
10441
    template < typename T1, typename T2 >
10442
    struct is_same
10443
    {
10444
      static const bool value = false;
10445
    };
10446

  
10447
    template < typename T >
10448
    struct is_same<T, T>
10449
    {
10450
      static const bool value = true;
10451
    };
10452

  
10453
    template < typename T1, typename T2 >
10454
    auto
10455
    add(T1 a1, T2 a2) -> decltype(a1 + a2)
10456
    {
10457
      return a1 + a2;
10458
    }
10459

  
10460
    int
10461
    test(const int c, volatile int v)
10462
    {
10463
      static_assert(is_same<int, decltype(0)>::value == true, "");
10464
      static_assert(is_same<int, decltype(c)>::value == false, "");
10465
      static_assert(is_same<int, decltype(v)>::value == false, "");
10466
      auto ac = c;
10467
      auto av = v;
10468
      auto sumi = ac + av + 'x';
10469
      auto sumf = ac + av + 1.0;
10470
      static_assert(is_same<int, decltype(ac)>::value == true, "");
10471
      static_assert(is_same<int, decltype(av)>::value == true, "");
10472
      static_assert(is_same<int, decltype(sumi)>::value == true, "");
10473
      static_assert(is_same<int, decltype(sumf)>::value == false, "");
10474
      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
10475
      return (sumf > 0.0) ? sumi : add(c, v);
10476
    }
10477

  
10478
  }
10479

  
10480
  namespace test_noexcept
10481
  {
10482

  
10483
    int f() { return 0; }
10484
    int g() noexcept { return 0; }
10485

  
10486
    static_assert(noexcept(f()) == false, "");
10487
    static_assert(noexcept(g()) == true, "");
10488

  
10489
  }
10490

  
10491
  namespace test_constexpr
10492
  {
10493

  
10494
    template < typename CharT >
10495
    unsigned long constexpr
10496
    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
10497
    {
10498
      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
10499
    }
10500

  
10501
    template < typename CharT >
10502
    unsigned long constexpr
10503
    strlen_c(const CharT *const s) noexcept
10504
    {
10505
      return strlen_c_r(s, 0UL);
10506
    }
10507

  
10508
    static_assert(strlen_c("") == 0UL, "");
10509
    static_assert(strlen_c("1") == 1UL, "");
10510
    static_assert(strlen_c("example") == 7UL, "");
10511
    static_assert(strlen_c("another\0example") == 7UL, "");
10512

  
10513
  }
10514

  
10515
  namespace test_rvalue_references
10516
  {
10517

  
10518
    template < int N >
10519
    struct answer
10520
    {
10521
      static constexpr int value = N;
10522
    };
10523

  
10524
    answer<1> f(int&)       { return answer<1>(); }
10525
    answer<2> f(const int&) { return answer<2>(); }
10526
    answer<3> f(int&&)      { return answer<3>(); }
10527

  
10528
    void
10529
    test()
10530
    {
10531
      int i = 0;
10532
      const int c = 0;
10533
      static_assert(decltype(f(i))::value == 1, "");
10534
      static_assert(decltype(f(c))::value == 2, "");
10535
      static_assert(decltype(f(0))::value == 3, "");
10536
    }
10537

  
10538
  }
10539

  
10540
  namespace test_uniform_initialization
10541
  {
10542

  
10543
    struct test
10544
    {
10545
      static const int zero {};
10546
      static const int one {1};
10547
    };
10548

  
10549
    static_assert(test::zero == 0, "");
10550
    static_assert(test::one == 1, "");
10551

  
10552
  }
10553

  
10554
  namespace test_lambdas
10555
  {
10556

  
10557
    void
10558
    test1()
10559
    {
10560
      auto lambda1 = [](){};
10561
      auto lambda2 = lambda1;
10562
      lambda1();
10563
      lambda2();
10564
    }
10565

  
10566
    int
10567
    test2()
10568
    {
10569
      auto a = [](int i, int j){ return i + j; }(1, 2);
10570
      auto b = []() -> int { return '0'; }();
10571
      auto c = [=](){ return a + b; }();
10572
      auto d = [&](){ return c; }();
10573
      auto e = [a, &b](int x) mutable {
10574
        const auto identity = [](int y){ return y; };
10575
        for (auto i = 0; i < a; ++i)
10576
          a += b--;
10577
        return x + identity(a + b);
10578
      }(0);
10579
      return a + b + c + d + e;
10580
    }
10581

  
10582
    int
10583
    test3()
10584
    {
10585
      const auto nullary = [](){ return 0; };
10586
      const auto unary = [](int x){ return x; };
10587
      using nullary_t = decltype(nullary);
10588
      using unary_t = decltype(unary);
10589
      const auto higher1st = [](nullary_t f){ return f(); };
10590
      const auto higher2nd = [unary](nullary_t f1){
10591
        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
10592
      };
10593
      return higher1st(nullary) + higher2nd(nullary)(unary);
10594
    }
10595

  
10596
  }
10597

  
10598
  namespace test_variadic_templates
10599
  {
10600

  
10601
    template <int...>
10602
    struct sum;
10603

  
10604
    template <int N0, int... N1toN>
10605
    struct sum<N0, N1toN...>
10606
    {
10607
      static constexpr auto value = N0 + sum<N1toN...>::value;
10608
    };
10609

  
10610
    template <>
10611
    struct sum<>
10612
    {
10613
      static constexpr auto value = 0;
10614
    };
10615

  
10616
    static_assert(sum<>::value == 0, "");
10617
    static_assert(sum<1>::value == 1, "");
10618
    static_assert(sum<23>::value == 23, "");
10619
    static_assert(sum<1, 2>::value == 3, "");
10620
    static_assert(sum<5, 5, 11>::value == 21, "");
10621
    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
10622

  
10623
  }
10624

  
10625
  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
10626
  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
10627
  // because of this.
10628
  namespace test_template_alias_sfinae
10629
  {
10630

  
10631
    struct foo {};
10632

  
10633
    template<typename T>
10634
    using member = typename T::member_type;
10635

  
10636
    template<typename T>
10637
    void func(...) {}
10638

  
10639
    template<typename T>
10640
    void func(member<T>*) {}
10641

  
10642
    void test();
10643

  
10644
    void test() { func<foo>(0); }
10645

  
10646
  }
10647

  
10648
}  // namespace cxx11
10649

  
10650
#endif  // __cplusplus >= 201103L
10651

  
10652
]])
10653

  
10654

  
10655
dnl  Tests for new features in C++14
10656

  
10657
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
10658

  
10659
// If the compiler admits that it is not ready for C++14, why torture it?
10660
// Hopefully, this will speed up the test.
10661

  
10662
#ifndef __cplusplus
10663

  
10664
#error "This is not a C++ compiler"
10665

  
10666
#elif __cplusplus < 201402L
10667

  
10668
#error "This is not a C++14 compiler"
10669

  
10670
#else
10671

  
10672
namespace cxx14
10673
{
10674

  
10675
  namespace test_polymorphic_lambdas
10676
  {
10677

  
10678
    int
10679
    test()
10680
    {
10681
      const auto lambda = [](auto&&... args){
10682
        const auto istiny = [](auto x){
10683
          return (sizeof(x) == 1UL) ? 1 : 0;
10684
        };
10685
        const int aretiny[] = { istiny(args)... };
10686
        return aretiny[0];
10687
      };
10688
      return lambda(1, 1L, 1.0f, '1');
10689
    }
10690

  
10691
  }
10692

  
10693
  namespace test_binary_literals
10694
  {
10695

  
10696
    constexpr auto ivii = 0b0000000000101010;
10697
    static_assert(ivii == 42, "wrong value");
10698

  
10699
  }
10700

  
10701
  namespace test_generalized_constexpr
10702
  {
10703

  
10704
    template < typename CharT >
10705
    constexpr unsigned long
10706
    strlen_c(const CharT *const s) noexcept
10707
    {
10708
      auto length = 0UL;
10709
      for (auto p = s; *p; ++p)
10710
        ++length;
10711
      return length;
10712
    }
10713

  
10714
    static_assert(strlen_c("") == 0UL, "");
10715
    static_assert(strlen_c("x") == 1UL, "");
10716
    static_assert(strlen_c("test") == 4UL, "");
10717
    static_assert(strlen_c("another\0test") == 7UL, "");
10718

  
10719
  }
10720

  
10721
  namespace test_lambda_init_capture
10722
  {
10723

  
10724
    int
10725
    test()
10726
    {
10727
      auto x = 0;
10728
      const auto lambda1 = [a = x](int b){ return a + b; };
10729
      const auto lambda2 = [a = lambda1(x)](){ return a; };
10730
      return lambda2();
10731
    }
10732

  
10733
  }
10734

  
10735
  namespace test_digit_separators
10736
  {
10737

  
10738
    constexpr auto ten_million = 100'000'000;
10739
    static_assert(ten_million == 100000000, "");
10740

  
10741
  }
10742

  
10743
  namespace test_return_type_deduction
10744
  {
10745

  
10746
    auto f(int& x) { return x; }
10747
    decltype(auto) g(int& x) { return x; }
10748

  
10749
    template < typename T1, typename T2 >
10750
    struct is_same
10751
    {
10752
      static constexpr auto value = false;
10753
    };
10754

  
10755
    template < typename T >
10756
    struct is_same<T, T>
10757
    {
10758
      static constexpr auto value = true;
10759
    };
10760

  
10761
    int
10762
    test()
10763
    {
10764
      auto x = 0;
10765
      static_assert(is_same<int, decltype(f(x))>::value, "");
10766
      static_assert(is_same<int&, decltype(g(x))>::value, "");
10767
      return x;
10768
    }
10769

  
10770
  }
10771

  
10772
}  // namespace cxx14
10773

  
10774
#endif  // __cplusplus >= 201402L
10775

  
10776
]])
10777

  
10778

  
10779
dnl  Tests for new features in C++17
10780

  
10781
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
10782

  
10783
// If the compiler admits that it is not ready for C++17, why torture it?
10784
// Hopefully, this will speed up the test.
10785

  
10786
#ifndef __cplusplus
10787

  
10788
#error "This is not a C++ compiler"
10789

  
10790
#elif __cplusplus <= 201402L
10791

  
10792
#error "This is not a C++17 compiler"
10793

  
10794
#else
10795

  
10796
#if defined(__clang__)
10797
  #define REALLY_CLANG
10798
#else
10799
  #if defined(__GNUC__)
10800
    #define REALLY_GCC
10801
  #endif
10802
#endif
10803

  
10804
#include <initializer_list>
10805
#include <utility>
10806
#include <type_traits>
10807

  
10808
namespace cxx17
10809
{
10810

  
10811
#if !defined(REALLY_CLANG)
10812
  namespace test_constexpr_lambdas
10813
  {
10814

  
10815
    // TODO: test it with clang++ from git
10816

  
10817
    constexpr int foo = [](){return 42;}();
10818

  
10819
  }
10820
#endif // !defined(REALLY_CLANG)
10821

  
10822
  namespace test::nested_namespace::definitions
10823
  {
10824

  
10825
  }
10826

  
10827
  namespace test_fold_expression
10828
  {
10829

  
10830
    template<typename... Args>
10831
    int multiply(Args... args)
10832
    {
10833
      return (args * ... * 1);
10834
    }
10835

  
10836
    template<typename... Args>
10837
    bool all(Args... args)
10838
    {
10839
      return (args && ...);
10840
    }
10841

  
10842
  }
10843

  
10844
  namespace test_extended_static_assert
10845
  {
10846

  
10847
    static_assert (true);
10848

  
10849
  }
10850

  
10851
  namespace test_auto_brace_init_list
10852
  {
10853

  
10854
    auto foo = {5};
10855
    auto bar {5};
10856

  
10857
    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
10858
    static_assert(std::is_same<int, decltype(bar)>::value);
10859
  }
10860

  
10861
  namespace test_typename_in_template_template_parameter
10862
  {
10863

  
10864
    template<template<typename> typename X> struct D;
10865

  
10866
  }
10867

  
10868
  namespace test_fallthrough_nodiscard_maybe_unused_attributes
10869
  {
10870

  
10871
    int f1()
10872
    {
10873
      return 42;
10874
    }
10875

  
10876
    [[nodiscard]] int f2()
10877
    {
10878
      [[maybe_unused]] auto unused = f1();
10879

  
10880
      switch (f1())
10881
      {
10882
      case 17:
10883
        f1();
10884
        [[fallthrough]];
10885
      case 42:
10886
        f1();
10887
      }
10888
      return f1();
10889
    }
10890

  
10891
  }
10892

  
10893
  namespace test_extended_aggregate_initialization
10894
  {
10895

  
10896
    struct base1
10897
    {
10898
      int b1, b2 = 42;
10899
    };
10900

  
10901
    struct base2
10902
    {
10903
      base2() {
10904
        b3 = 42;
10905
      }
10906
      int b3;
10907
    };
10908

  
10909
    struct derived : base1, base2
10910
    {
10911
        int d;
10912
    };
10913

  
10914
    derived d1 {{1, 2}, {}, 4};  // full initialization
10915
    derived d2 {{}, {}, 4};      // value-initialized bases
10916

  
10917
  }
10918

  
10919
  namespace test_general_range_based_for_loop
10920
  {
10921

  
10922
    struct iter
10923
    {
10924
      int i;
10925

  
10926
      int& operator* ()
10927
      {
10928
        return i;
10929
      }
10930

  
10931
      const int& operator* () const
10932
      {
10933
        return i;
10934
      }
10935

  
10936
      iter& operator++()
10937
      {
10938
        ++i;
10939
        return *this;
10940
      }
10941
    };
10942

  
10943
    struct sentinel
10944
    {
10945
      int i;
10946
    };
10947

  
10948
    bool operator== (const iter& i, const sentinel& s)
10949
    {
10950
      return i.i == s.i;
10951
    }
10952

  
10953
    bool operator!= (const iter& i, const sentinel& s)
10954
    {
10955
      return !(i == s);
10956
    }
10957

  
10958
    struct range
10959
    {
10960
      iter begin() const
10961
      {
10962
        return {0};
10963
      }
10964

  
10965
      sentinel end() const
10966
      {
10967
        return {5};
10968
      }
10969
    };
10970

  
10971
    void f()
10972
    {
10973
      range r {};
10974

  
10975
      for (auto i : r)
10976
      {
10977
        [[maybe_unused]] auto v = i;
10978
      }
10979
    }
10980

  
10981
  }
10982

  
10983
  namespace test_lambda_capture_asterisk_this_by_value
10984
  {
10985

  
10986
    struct t
10987
    {
10988
      int i;
10989
      int foo()
10990
      {
10991
        return [*this]()
10992
        {
10993
          return i;
10994
        }();
10995
      }
10996
    };
10997

  
10998
  }
10999

  
11000
  namespace test_enum_class_construction
11001
  {
11002

  
11003
    enum class byte : unsigned char
11004
    {};
11005

  
11006
    byte foo {42};
11007

  
11008
  }
11009

  
11010
  namespace test_constexpr_if
11011
  {
11012

  
11013
    template <bool cond>
11014
    int f ()
11015
    {
11016
      if constexpr(cond)
11017
      {
11018
        return 13;
11019
      }
11020
      else
11021
      {
11022
        return 42;
11023
      }
11024
    }
11025

  
11026
  }
11027

  
11028
  namespace test_selection_statement_with_initializer
11029
  {
11030

  
11031
    int f()
11032
    {
11033
      return 13;
11034
    }
11035

  
11036
    int f2()
11037
    {
11038
      if (auto i = f(); i > 0)
11039
      {
11040
        return 3;
11041
      }
11042

  
11043
      switch (auto i = f(); i + 4)
11044
      {
11045
      case 17:
11046
        return 2;
11047

  
11048
      default:
11049
        return 1;
11050
      }
11051
    }
11052

  
11053
  }
11054

  
11055
#if !defined(REALLY_CLANG)
11056
  namespace test_template_argument_deduction_for_class_templates
11057
  {
11058

  
11059
    // TODO: test it with clang++ from git
11060

  
11061
    template <typename T1, typename T2>
11062
    struct pair
11063
    {
11064
      pair (T1 p1, T2 p2)
11065
        : m1 {p1},
11066
          m2 {p2}
11067
      {}
11068

  
11069
      T1 m1;
11070
      T2 m2;
11071
    };
11072

  
11073
    void f()
11074
    {
11075
      [[maybe_unused]] auto p = pair{13, 42u};
11076
    }
11077

  
11078
  }
11079
#endif // !defined(REALLY_CLANG)
11080

  
11081
  namespace test_non_type_auto_template_parameters
11082
  {
11083

  
11084
    template <auto n>
11085
    struct B
11086
    {};
11087

  
11088
    B<5> b1;
11089
    B<'a'> b2;
11090

  
11091
  }
11092

  
11093
#if !defined(REALLY_CLANG)
11094
  namespace test_structured_bindings
11095
  {
11096

  
11097
    // TODO: test it with clang++ from git
11098

  
11099
    int arr[2] = { 1, 2 };
11100
    std::pair<int, int> pr = { 1, 2 };
11101

  
11102
    auto f1() -> int(&)[2]
11103
    {
11104
      return arr;
11105
    }
11106

  
11107
    auto f2() -> std::pair<int, int>&
11108
    {
11109
      return pr;
11110
    }
11111

  
11112
    struct S
11113
    {
11114
      int x1 : 2;
11115
      volatile double y1;
11116
    };
11117

  
11118
    S f3()
11119
    {
11120
      return {};
11121
    }
11122

  
11123
    auto [ x1, y1 ] = f1();
11124
    auto& [ xr1, yr1 ] = f1();
11125
    auto [ x2, y2 ] = f2();
11126
    auto& [ xr2, yr2 ] = f2();
11127
    const auto [ x3, y3 ] = f3();
11128

  
11129
  }
11130
#endif // !defined(REALLY_CLANG)
11131

  
11132
#if !defined(REALLY_CLANG)
11133
  namespace test_exception_spec_type_system
11134
  {
11135

  
11136
    // TODO: test it with clang++ from git
11137

  
11138
    struct Good {};
11139
    struct Bad {};
11140

  
11141
    void g1() noexcept;
11142
    void g2();
11143

  
11144
    template<typename T>
11145
    Bad
11146
    f(T*, T*);
11147

  
11148
    template<typename T1, typename T2>
11149
    Good
11150
    f(T1*, T2*);
11151

  
11152
    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
11153

  
11154
  }
11155
#endif // !defined(REALLY_CLANG)
11156

  
11157
  namespace test_inline_variables
11158
  {
11159

  
11160
    template<class T> void f(T)
11161
    {}
11162

  
11163
    template<class T> inline T g(T)
11164
    {
11165
      return T{};
11166
    }
11167

  
11168
    template<> inline void f<>(int)
11169
    {}
11170

  
11171
    template<> int g<>(int)
11172
    {
11173
      return 5;
11174
    }
11175

  
11176
  }
11177

  
11178
}  // namespace cxx17
11179

  
11180
#endif  // __cplusplus <= 201402L
11181

  
11182
]])
trunk/config/configure.ac (revision 4698) → trunk/config/configure.ac (working copy)
23 23
ac_cv_prog_cxx_g=no
24 24
AC_PROG_CXX
25 25
AC_PROG_CXXCPP
26
AX_CXX_COMPILE_STDCXX(11, noext, optional)
26 27
# Don't use -g to compile C code
27 28
ac_cv_prog_cc_g=no
28 29
AC_PROG_CC
......
129 130
    fi
130 131
fi
131 132

  
133

  
132 134
AC_MSG_CHECKING([whether to use the lens database for Nikon lens names])
133 135
AC_ARG_ENABLE(lensdata,
134 136
    [  --disable-lensdata      do not use the lens database for Nikon lens names ],
......
355 357
  AC_SUBST([GCC_VERSION])
356 358
])
357 359

  
358
# 1188 v0.26 uses c++98
359
# 1188 v0.27 should have an option to specify versions such as c++11
360
case "$host_os" in
361
    *cygwin*)
362
        CPPFLAGS="$CPPFLAGS -std=gnu++98"  # cygwin requires gnu++98 to support snprintf
363
    ;;
364
    *ming*)
365
        CPPFLAGS="$CPPFLAGS"               # mingw doesn't link pthreads if you specify -std !!
366
    ;;
367
    *)
368
        if [ $GCC_VERSION -le 5 ]; then CPPFLAGS="$CPPFLAGS -std=c++98"    # // most others use c++98
369
        else                            CPPFLAGS="$CPPFLAGS -std=gnu++98"  # // but not GCC 6
370
        fi
371
    ;;
372
esac
360
AC_ARG_ENABLE(stdcpp11,
361
    [  --disable-stdcpp11    do not use the c++11 standard ],
362
    STDCPP11_SUPPORT=$enableval, STDCPP11_SUPPORT=$visibility)
363
AC_MSG_RESULT($STDCPP11_SUPPORT)
364
if test "$STDCPP11_SUPPORT" = "yes"; then
365
    CPPFLAGS="${CPPFLAGS} -std=c++11 -DEXV_USING_CPP_ELEVEN"
366
else
367
    # 1188 v0.26 uses c++98
368
    # 1188 v0.27 should have an option to specify versions such as c++11
369
    case "$host_os" in
370
        *cygwin*)
371
            CPPFLAGS="$CPPFLAGS -std=gnu++98"  # cygwin requires gnu++98 to support snprintf
372
        ;;
373
        *ming*)
374
            CPPFLAGS="$CPPFLAGS"               # mingw doesn't link pthreads if you specify -std !!
375
        ;;
376
        *)
377
            if [ $GCC_VERSION -le 5 ]; then CPPFLAGS="$CPPFLAGS -std=c++98"    # // most others use c++98
378
            else                            CPPFLAGS="$CPPFLAGS -std=gnu++98"  # // but not GCC 6
379
            fi
380
        ;;
381
    esac
382
fi
373 383

  
374 384
# ---------------------------------------------------------------------------
375 385
# Create output files.
(3-3/6)