diff --git a/cmake/modules/FindCXX11Features.cmake b/cmake/modules/FindCXX11Features.cmake index fbb96ce4e53162fb37ee12ebcfc5fb24493d43ec..ce402a962e862b77913a078d7a678ab63535a826 100644 --- a/cmake/modules/FindCXX11Features.cmake +++ b/cmake/modules/FindCXX11Features.cmake @@ -288,4 +288,27 @@ CHECK_CXX_SOURCE_COMPILES(" } " HAVE_RVALUE_REFERENCES ) + +# initializer list +CHECK_CXX_SOURCE_COMPILES(" + #include <initializer_list> + #include <vector> + + struct A + { + A(std::initializer_list<int> il) + : vec(il) + {} + + std::vector<int> vec; + }; + + int main(void) + { + A a{1,3,4,5}; + return 0; + } +" HAVE_INITIALIZER_LIST +) + cmake_pop_check_state() diff --git a/config.h.cmake b/config.h.cmake index af32e048e87c7fa5f694b68ff0808a918bf0103e..dde41d58022b09cc842ff6d71aa1854a71fb20e1 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -157,6 +157,9 @@ /* Define to 1 if rvalue references are supported */ #cmakedefine HAVE_RVALUE_REFERENCES 1 +/* Define to 1 if initializer list is supported */ +#cmakedefine HAVE_INITIALIZER_LIST 1 + /* Include always useful headers */ #include <dune/common/deprecated.hh> #include <dune/common/unused.hh> diff --git a/dune/common/fvector.hh b/dune/common/fvector.hh index 8fd550e69780aad247ac40bebde1c942a7569fd5..6084355cc1ac8baa5fc11c9f247d5d1d5db8118a 100644 --- a/dune/common/fvector.hh +++ b/dune/common/fvector.hh @@ -9,6 +9,7 @@ #include <cstdlib> #include <complex> #include <cstring> +#include <utility> #include "typetraits.hh" #include "exceptions.hh" @@ -98,8 +99,22 @@ namespace Dune { typedef typename Base::size_type size_type; typedef typename Base::value_type value_type; - //! Constructor making uninitialized vector - FieldVector() {} + //! Constructor making default-initialized vector + FieldVector() + // Use C++11 unified initialization if available - tends to generate + // fastest code +#if HAVE_INITIALIZER_LIST + : _data{} + {} +#else + { + // fall back to library approach - this gives faster code than array placement + // new. Apart from that, placement new may create problems if K is a complex + // type. In that case, the default constructor of the _data elements has already + // been called and may have allocated memory. + std::fill(_data.begin(),_data.end(),K()); + } +#endif //! Constructor making vector with identical coordinates explicit FieldVector (const K& t) @@ -205,7 +220,9 @@ namespace Dune { //===== construction /** \brief Default constructor */ - FieldVector () {} + FieldVector () + : _data() + {} /** \brief Constructor with a given scalar */ FieldVector (const K& k) : _data(k) {} diff --git a/m4/CMakeLists.txt b/m4/CMakeLists.txt index 40c791eb1a29f6d3837fee16a753360a7a05ba01..1b062c9cf46b2483d617fe4be737b0dc09f24426 100644 --- a/m4/CMakeLists.txt +++ b/m4/CMakeLists.txt @@ -13,6 +13,7 @@ install(PROGRAMS cxx0x_static_assert.m4 cxx0x_variadic.m4 cxx0x_variadic_constructor_sfinae.m4 + cxx11_initializer_list.m4 cxx11_conditional.m4 dune.m4 dune_all.m4 diff --git a/m4/Makefile.am b/m4/Makefile.am index 32fbabbd59d89418cc3fe28357981e2308b74613..bfbdb06fbf56007c359eb62ed5cb1f6775905118 100644 --- a/m4/Makefile.am +++ b/m4/Makefile.am @@ -17,6 +17,7 @@ ALLM4S = \ cxx0x_static_assert.m4 \ cxx0x_variadic.m4 \ cxx0x_variadic_constructor_sfinae.m4 \ + cxx11_initializer_list.m4 \ cxx11_conditional.m4 \ dune.m4 \ dune_all.m4 \ diff --git a/m4/cxx11_initializer_list.m4 b/m4/cxx11_initializer_list.m4 new file mode 100644 index 0000000000000000000000000000000000000000..04fc9ff86bc43fe9e90312a6a5f303585ca1f5aa --- /dev/null +++ b/m4/cxx11_initializer_list.m4 @@ -0,0 +1,37 @@ +# tests for C++11 initializer list support +# the associated macro is called HAVE_INITIALIZER_LIST + +AC_DEFUN([INITIALIZER_LIST_CHECK],[ + AC_CACHE_CHECK([whether std::initializer_list is supported], dune_cv_initializer_list_support, [ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([GXX0X]) + AC_LANG_PUSH([C++]) + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([ + + #include <initializer_list> + #include <vector> + + struct A + { + + A(std::initializer_list<int> il) + : vec(il) + {} + + std::vector<int> vec; + }; + + ], + [ + A a{1,3,4,5}; + return 0; + ])], + dune_cv_initializer_list_support=yes, + dune_cv_initializer_list_support=no) + AC_LANG_POP + ]) + if test "x$dune_cv_initializer_list_support" = xyes; then + AC_DEFINE(HAVE_INITIALIZER_LIST, 1, [Define to 1 if std::initializer_list is supported]) + fi +]) diff --git a/m4/dune_common.m4 b/m4/dune_common.m4 index 639397b43e64431b75c88374f574c0e325818cab..d9debceff2c364d0257acd3fef2190bb4cb31048 100644 --- a/m4/dune_common.m4 +++ b/m4/dune_common.m4 @@ -24,6 +24,7 @@ AC_DEFUN([DUNE_COMMON_CHECKS], AC_REQUIRE([SHARED_PTR]) AC_REQUIRE([VARIADIC_TEMPLATES_CHECK]) AC_REQUIRE([RVALUE_REFERENCES_CHECK]) + AC_REQUIRE([INITIALIZER_LIST_CHECK]) AC_REQUIRE([CXX11_CONDITIONAL_CHECK]) AC_REQUIRE([DUNE_BOOST_BASE]) AC_REQUIRE([MAKE_SHARED]) @@ -78,7 +79,7 @@ AC_DEFUN([DUNE_COMMON_CHECKS], AC_DEFUN([DUNE_COMMON_CHECK_MODULE], [ DUNE_CHECK_MODULES([dune-common], [common/stdstreams.hh], - [#ifndef DUNE_MINIMAL_DEBUG_LEVEL + [#ifndef DUNE_MINIMAL_DEBUG_LEVEL #define DUNE_MINIMAL_DEBUG_LEVEL 1 #endif Dune::derr.active();])