-dnl -------------------------------------------------------------
-dnl See if there is a compiler flag to enable C++1x features
-dnl
-dnl Usage: DEAL_II_CHECK_CXX1X
-dnl
-dnl -------------------------------------------------------------
-AC_DEFUN(DEAL_II_CHECK_CXX1X, dnl
-[
- AC_MSG_CHECKING(whether compiler has a flag to support C++2011)
-
- dnl See if -std=c++0x exists
- OLD_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS=-std=c++0x
- AC_TRY_COMPILE([], [;],
- [
- AC_MSG_RESULT(yes)
- test_cxx1x=yes
- ],
- [
- AC_MSG_RESULT(no)
- test_cxx1x=no
- ])
- CXXFLAGS="${OLD_CXXFLAGS}"
-
- dnl If the flag above works, then see if the compiler is complete
- dnl enough in this area
- if test "x$test_cxx1x" = "xyes" ; then
- DEAL_II_CHECK_CXX1X_COMPONENTS("-std=c++0x")
- fi
-])
-
-
-dnl -------------------------------------------------------------
-dnl Given the command line flag specified as argument to this macro,
-dnl test whether all components that we need from the C++1X
-dnl standard are actually available. If so, add the flag to
-dnl CXXFLAGSG and CXXFLAGSO, and set a flag in config.h
-dnl
-dnl Usage: DEAL_II_CHECK_CXX1X_COMPONENTS(cxxflag)
-dnl
-dnl -------------------------------------------------------------
-AC_DEFUN(DEAL_II_CHECK_CXX1X_COMPONENTS, dnl
-[
- OLD_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS="$1"
-
- all_cxx1x_classes_available=yes
-
- AC_MSG_CHECKING(for std::array)
- AC_TRY_COMPILE(
- [#include <array>],
- [ std::array<int,3> p; p[0];],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::condition_variable)
- AC_TRY_COMPILE(
- [#include <condition_variable> ],
- [ std::condition_variable c; c.notify_all()],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::function and std::bind)
- AC_TRY_COMPILE(
- [#include <functional>
- void f(int, double); ],
- [ std::function<void (int)>
- g = std::bind (f, std::placeholders::_1, 1.1) ;],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- dnl Make sure we don't run into GCC bug 35569
- AC_MSG_CHECKING(for std::bind works with rvalues)
- AC_TRY_COMPILE(
- [#include <functional>
- void f(int); ],
- [ using namespace std;
- using namespace std::placeholders;
- bind(multiplies<int>(),4,_1)(5); ;],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::shared_ptr)
- AC_TRY_COMPILE(
- [#include <memory>],
- [ std::shared_ptr<int> p(new int(3))],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::thread)
- AC_TRY_COMPILE(
- [#include <thread>
- void f(int); ],
- [ std::thread t(f,1); t.join();],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- dnl On some systems with gcc 4.5.0, we can compile the code
- dnl above but it will throw an exception when run. So test
- dnl that as well. The test will only be successful if we have
- dnl libpthread available, so link it in for this test. If
- dnl multithreading is requested, it will be added to CXXFLAGS
- dnl later on so there is no need to do this here.
- CXXFLAGS="$1 -lpthread"
- AC_MSG_CHECKING(whether std::thread actually works)
- AC_TRY_RUN(
- [#include <thread>
- void f(int) {}
- int main() { std::thread t(f,1); t.join(); } ],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
- CXXFLAGS="$1"
-
- AC_MSG_CHECKING(for std::mutex)
- AC_TRY_COMPILE(
- [#include <mutex> ],
- [ std::mutex m; m.lock();],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::tuple)
- AC_TRY_COMPILE(
- [#include <tuple>],
- [ std::tuple<int,double,char> p(1,1.1,'a')],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- AC_MSG_CHECKING(for std::type_traits)
- AC_TRY_COMPILE(
- [#include <type_traits>],
- [ const bool m0 = std::is_trivial<double>::value;
- const bool m1 = std::is_standard_layout<double>::value;
- const bool m2 = std::is_pod<double>::value; ],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); all_cxx1x_classes_available=no ]
- )
-
- CXXFLAGS="${OLD_CXXFLAGS}"
-
- dnl If the above classes and operations are all defined then we can
- dnl use the corresponding flag in CXXFLAGS* to switch on support and
- dnl correspondingly use the C++ classes instead of the BOOST classes
- AC_MSG_CHECKING(whether C++1x support is complete enough)
- if test "x$all_cxx1x_classes_available" = "xyes" ; then
- AC_MSG_RESULT(yes)
-
- CXXFLAGSG="$CXXFLAGSG $1"
- CXXFLAGSO="$CXXFLAGSO $1"
-
- AC_DEFINE(DEAL_II_CAN_USE_CXX1X, 1,
- [Defined if the compiler we use supports the C++2011 standard
- well enough to allow using the standard library classes instead
- of the corresponding BOOST classes.])
-
-
- dnl Also test for a couple C++1x things that we don't use in the library
- dnl but that users may want to use in their applications and that we
- dnl might want to test in the testsuite
- OLD_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS="$CXXFLAGSG"
-
- extra_cxx1x_features_available=yes
-
- AC_MSG_CHECKING(for auto typed variables)
- AC_TRY_COMPILE(
- [#include <vector>],
- [
- std::vector<int> v;
- auto i = v.begin();
- *i;
- ],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); extra_cxx1x_features_available=no ]
- )
-
- AC_MSG_CHECKING(for range-based for)
- AC_TRY_COMPILE(
- [#include <vector>],
- [
- std::vector<int> v;
- for (std::vector<int>::iterator i : v)
- *i;
- ],
- [ AC_MSG_RESULT(yes) ],
- [ AC_MSG_RESULT(no); extra_cxx1x_features_available=no ]
- )
-
- CXXFLAGS="${OLD_CXXFLAGS}"
-
- dnl Right now, do nothing with this information since we don't
- dnl have any compiler that gets all this right (gcc 4.5 included)
- dnl and that we could use to test these features.
- else
- AC_MSG_RESULT(no)
-
- dnl Intel icc 12.1 has this crazy behavior where it needs -std=c++0x
- dnl to compile BOOST, but it fails every single one of the header
- dnl file tests above. So we end up here. Work around this by using
- dnl the flag even though we can't use a single piece of functionality.
- if test "x$GXX_VERSION" = "xintel_icc12" ; then
- CXXFLAGSG="$CXXFLAGSG $1"
- CXXFLAGSO="$CXXFLAGSO $1"
- fi
- fi
-])
INCLUDE(CheckCXXSourceCompiles)
+INCLUDE(CheckCXXSourceRuns)
INCLUDE(CheckIncludeFiles)
#
-# Check for various CXX features.
+# Check for various C++ language features
#
+CHECK_CXX_SOURCE_COMPILES( # TODO: Phase out
+ "
+ #include <ostream>
+ int main(){return 0;}
+ "
+ HAVE_STD_OSTREAM_HEADER)
+
+CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <iosfwd>
+ int main(){return 0;}
+ "
+ HAVE_STD_IOSFWD_HEADER)
+
+
+
#
-# Check whether the std::vector::iterator is just a plain pointer
+# C++0x Support:
#
+
+
+# See if there is a compiler flag to enable C++0x features
+# (Only test for -std=c++0x for the moment.)
+
+# Set CMAKE_REQUIRED_FLAGS for the unit tests
+LIST(APPEND CMAKE_REQUIRED_FLAGS "-std=c++0x")
+
CHECK_CXX_SOURCE_COMPILES(
"
- #include <vector>
- template <typename T> void f(T) {}
- template void f(int *);
- template void f(std::vector<int>::iterator);
- int main(){return 0;}
+ int main(){ return 0; }
"
- DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER)
+ DEAL_II_HAVE_CXX0X_FLAG)
+
+
+
+IF(DEAL_II_HAVE_CXX0X_FLAG)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <array>
+ std::array<int,3> p;
+ int main(){ p[0]; return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_ARRAY)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <condition_variable>
+ std::condition_variable c;
+ int main(){ c.notify_all(); return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_CONDITION_VARIABLE)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <functional>
+ void f(int, double){}
+ std::function<void (int)> g = std::bind (f, std::placeholders::_1,1.1);
+ int main(){ return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_FUNCTIONAL)
+
+ # Make sure we don't run into GCC bug 35569
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <functional>
+ void f(int){}
+ using namespace std;
+ using namespace std::placeholders;
+ int main(){ bind(multiplies<int>(),4,_1)(5); return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_FUNCTIONAL_GCCBUG35569_OK)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <memory>
+ std::shared_ptr<int> p(new int(3));
+ int main(){ return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_SHARED_PTR)
+
+ LIST(APPEND CMAKE_REQUIRED_FLAGS "-lpthreads")
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <thread>
+ void f(int){}
+ int main(){ std::thread t(f,1); t.join(); return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_THREAD)
+
+ #On some systems with gcc 4.5.0, we can compile the code
+ #above but it will throw an exception when run. So test
+ #that as well. The test will only be successful if we have
+ #libpthread available, so link it in for this test. If
+ #multithreading is requested, it will be added to CXXFLAGS
+ #later on so there is no need to do this here.
+ CHECK_CXX_SOURCE_RUNS(
+ "
+ #include <thread>
+ void f(int){}
+ int main(){ std::thread t(f,1); t.join(); return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_THREAD_RUN_OK)
+
+ LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-lpthreads")
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <mutex>
+ std::mutex m;
+ int main(){ m.lock(); return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_MUTEX)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <tuple>],
+ std::tuple<int,double,char> p(1,1.1,'a');
+ int main(){ return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_TUPLE)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <type_traits>
+ const bool m0 = std::is_trivial<double>::value;
+ const bool m1 = std::is_standard_layout<double>::value;
+ const bool m2 = std::is_pod<double>::value;
+ int main(){ return 0; }
+ "
+ DEAL_II_HAVE_CXX0X_TYPE_TRAITS)
+
+ IF( DEAL_II_HAVE_CXX0X_ARRAY AND
+ DEAL_II_HAVE_CXX0X_CONDITION_VARIABLE AND
+ DEAL_II_HAVE_CXX0X_FUNCTIONAL AND
+ DEAL_II_HAVE_CXX0X_FUNCTIONAL_GCCBUG35569_OK AND
+ DEAL_II_HAVE_CXX0X_SHARED_PTR AND
+ DEAL_II_HAVE_CXX0X_THREAD AND
+ DEAL_II_HAVE_CXX0X_THREAD_RUN_OK AND
+ DEAL_II_HAVE_CXX0X_MUTEX AND
+ DEAL_II_HAVE_CXX0X_TUPLE AND
+ DEAL_II_HAVE_CXX0X_TYPE_TRAITS )
+
+ MESSAGE(STATUS "Sufficient C++0x support. Enabling -std=c++0x.")
+
+ SET(DEAL_II_CAN_USE_CXX1X TRUE)
+
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") # TODO
+
+ ELSE()
+
+ MESSAGE(STATUS "Insufficient C++0x support. Disabling -std=c++0x.")
+ ENDIF()
+
+ IF(DEAL_II_CAN_USE_CXX1X)
+ #
+ # Also test for a couple C++0x things that we don't use in the library
+ # but that users may want to use in their applications and that we
+ # might want to test in the testsuite
+ #
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <vector>
+ std::vector<int> v;
+ int main(){ auto i = v.begin(); *i; return 0;}
+ "
+ DEAL_II_HAVE_CXX0X_AUTO_TYPE)
+
+ CHECK_CXX_SOURCE_COMPILES(
+ "
+ #include <vector>],
+ std::vector<int> v;
+ int main(){ for (std::vector<int>::iterator i : v) *i; return 0;}
+ "
+ DEAL_II_HAVE_CXX0X_RANGE_BASED_FOR)
+
+ IF( DEAL_II_HAVE_CXX0X_AUTO_TYPE AND
+ DEAL_II_HAVE_CXX0X_RANGE_BASED_FOR )
+
+ MESSAGE(STATUS "Additional C++0x support available.")
+
+ SET(DEAL_II_CAN_USE_ADDITIONAL_CXX1X_FEATURES)
+
+ ENDIF()
+ ENDIF()
-IF(NOT DEAL_II_VECTOR_ITERATOR_IS_NOT_POINTER)
- SET(DEAL_II_VECTOR_ITERATOR_IS_POINTER 1)
ENDIF()
+LIST(REMOVE_ITEM CMAKE_REQUIRED_FLAGS "-std=c++0x")
+
+
#
# Checks for various header files:
#
-CHECK_INCLUDE_FILES("ostream" HAVE_STD_OSTREAM_HEADER) # TODO: remove this...
-CHECK_INCLUDE_FILES("iosfwd" HAVE_STD_IOSFWD_HEADER)
CHECK_INCLUDE_FILES("stdint.h" HAVE_STDINT_H)
CHECK_INCLUDE_FILES("stdlib.h" HAVE_STDLIB_H)
CHECK_INCLUDE_FILES("strings.h" HAVE_STRINGS_H)