diff --git a/test/triqs/arrays/const_view.cpp b/test/triqs/arrays/const_view.cpp new file mode 100644 index 00000000..a4786e34 --- /dev/null +++ b/test/triqs/arrays/const_view.cpp @@ -0,0 +1,41 @@ +/******************************************************************************* + * + * TRIQS: a Toolbox for Research in Interacting Quantum Systems + * + * Copyright (C) 2011 by O. Parcollet + * + * TRIQS is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * TRIQS. If not, see . + * + ******************************************************************************/ +#include "./common.hpp" +#include "./src/array.hpp" +#include + +using namespace triqs::arrays; + +int main(int argc, char **argv) { + + const array A = {1,2,3,4}; + + std::cerr << A.opt_flags<. + * + ******************************************************************************/ +#include "./common.hpp" +#include "./src/array.hpp" +#include + +using namespace triqs::arrays; + +auto bad (array const & a) DECL_AND_RETURN (a(range(0,3))); + +auto bad2 (array const & a) DECL_AND_RETURN (a(0)); + +array_view good(array const & a) {return a(range(0,3));} + + +int main(int argc, char **argv) { + + try { + + array A = {1,2,3,4}; + + std::cerr<<"A is "< {1,2,3,4} (range(0,3)); + TEST_ASSERT(!r.storage().is_weak); + std::cerr << r << r.storage().is_weak << std::endl ; + } + + { + auto r = array {1,2,3,4} (range(0,3))(); + std::cerr << r << r.storage().is_weak << std::endl ; + TEST_ASSERT(!r.storage().is_weak); + } + + { + auto r = good ( { 1,2,3,4} ); + std::cerr << " good "<< r << r.storage().is_weak << std::endl ; + } + + { + auto & r = bad2 ( { 1,2,3,4} ); + std::cerr << " bad2 " << r << std::endl ; + } + + { + auto r = bad ( { 1,2,3,4} ); + std::cerr << " bad " << r << r.storage().is_weak << std::endl ; + } + + } + catch (std::exception & e) { std::cout << e.what()< Boundcheck + // Meaning of the bits : + // 0 -> Const // 1,2 -> Predefined order : // 0 : None, 1 : C, 2 : Fortran - // 3,4 -> Init - // 0 : Noinit, 1 : NanInit, 2 : DefaultInit + // 3 -> Init the array + // 5 -> Boundcheck - constexpr ull_t BoundCheck = 1ull << 0; - constexpr ull_t TraversalOrderC = 1ull << 1; - constexpr ull_t TraversalOrderFortran = 1ull << 2; - //constexpr ull_t NanInit = 1ull << 3; - constexpr ull_t DefaultInit = 1ull << 4; + constexpr ull_t ConstView = 1ull << 0; + constexpr ull_t TraversalOrderC = 1ull << 1; + constexpr ull_t TraversalOrderFortran = 1ull << 2; + constexpr ull_t DefaultInit = 1ull << 3; + constexpr ull_t BoundCheck = 1ull << 5; #define BOUND_CHECK triqs::arrays::BoundCheck #define TRAVERSAL_ORDER_C triqs::arrays::TraversalOrderC @@ -55,10 +55,12 @@ namespace triqs { namespace arrays { constexpr ull_t get(ull_t f, ull_t a) { return ((f & (1ull<> a);} constexpr ull_t get2(ull_t f, ull_t a) { return ((f & ((1ull<> a);} + constexpr bool is_const (ull_t f) { return get (f,0) !=0;} + #ifdef TRIQS_ARRAYS_ENFORCE_BOUNDCHECK constexpr bool bound_check (ull_t f) { return true;} #else - constexpr bool bound_check (ull_t f) { return get (f, 0)!=0;} + constexpr bool bound_check (ull_t f) { return get (f, 5)!=0;} #endif constexpr bool traversal_order_c (ull_t f) { return get (f,1ull)!=0ull;} @@ -66,13 +68,11 @@ namespace triqs { namespace arrays { template< ull_t F> struct bound_check_trait { static constexpr bool value = bound_check(F); }; - constexpr ull_t init_mode (ull_t f) { return get2 (f,3);} - constexpr bool check_init_mode (ull_t f) { return get2 (f,3)!=3ull;} + constexpr ull_t init_mode (ull_t f) { return get (f,3);} template struct init_tag1; template<> struct init_tag1<0> { typedef Tag::no_init type;}; - //template<> struct init_tag1<1> { typedef Tag::nan_inf_init type;}; - template<> struct init_tag1<2> { typedef Tag::default_init type;}; + template<> struct init_tag1<1> { typedef Tag::default_init type;}; // for the init_tag, we pass the *whole* option flag. template struct init_tag : init_tag1 < init_mode(F)> {}; @@ -81,21 +81,21 @@ namespace triqs { namespace arrays { static constexpr bool bc = bound_check(F); static constexpr bool is_c = traversal_order_c(F); static constexpr bool is_f = traversal_order_fortran(F); - static constexpr bool inm = check_init_mode(F); static_assert ( (!( is_c && is_f)), "You asked C and Fortran traversal order at the same time..."); static_assert ( (!( (is_c || is_f) && To )), "You asked C or Fortran traversal order and gave a traversal order ..."); - static_assert ( (inm), "You asked nan and default init at the same time..."); }; #else #define TRIQS_FLAGS_GET(f,a) ((f & (1ull<> a) #define TRIQS_FLAGS_GET2(f,a) ((f & ((1ull<> a) - + + constexpr bool is_const (ull_t f) { return false;} // non const view on icc + #ifdef TRIQS_ARRAYS_ENFORCE_BOUNDCHECK template< ull_t F> struct bound_check_trait { static constexpr bool value = true;}; #else - template< ull_t F> struct bound_check_trait { static constexpr bool value = TRIQS_FLAGS_GET (F, 0)!=0; }; + template< ull_t F> struct bound_check_trait { static constexpr bool value = TRIQS_FLAGS_GET (F, 5)!=0; }; #endif template< ull_t F> struct traversal_order_c { static constexpr bool value = TRIQS_FLAGS_GET(F,1) !=0; }; @@ -105,8 +105,7 @@ namespace triqs { namespace arrays { template struct init_tag1; template<> struct init_tag1<0> { typedef Tag::no_init type;}; - //template<> struct init_tag1<1> { typedef Tag::nan_inf_init type;}; - template<> struct init_tag1<2> { typedef Tag::default_init type;}; + template<> struct init_tag1<1> { typedef Tag::default_init type;}; template struct init_tag : init_tag1 < init_mode_tr::value > {}; template struct assert_make_sense { };// no check on icc diff --git a/triqs/arrays/impl/indexmap_storage_pair.hpp b/triqs/arrays/impl/indexmap_storage_pair.hpp index b06b7a56..0551f436 100644 --- a/triqs/arrays/impl/indexmap_storage_pair.hpp +++ b/triqs/arrays/impl/indexmap_storage_pair.hpp @@ -52,6 +52,7 @@ namespace triqs { namespace arrays { typedef StorageType storage_type; typedef IndexMapType indexmap_type; static constexpr unsigned int rank = IndexMapType::domain_type::rank; + static constexpr ull_t opt_flags = OptionFlags; protected: indexmap_type indexmap_; @@ -188,7 +189,7 @@ namespace triqs { namespace arrays { // Evaluation and slices template typename std::enable_if< - (!clef::is_any_lazy::value) && (indexmaps::slicer::r_type::domain_type::rank==0) + (!clef::is_any_lazy::value) && (indexmaps::slicer::r_type::domain_type::rank==0) && !flags::is_const(OptionFlags) , value_type &>::type operator()(Args const & ... args) { return storage_[indexmap_(args...)]; } @@ -203,7 +204,8 @@ namespace triqs { namespace arrays { //typedef typename std::conditional::type, value_type>::type V2; typedef value_type V2; static_assert(IM2::domain_type::rank !=0, "Internal error"); - typedef typename ISPViewType::type type; + static constexpr ull_t optmodif = (is_const ? ConstView : 0ull); + typedef typename ISPViewType::type type; }; // change here only for debug @@ -211,7 +213,7 @@ namespace triqs { namespace arrays { #ifndef TRIQS_ARRAYS_SLICE_DEFAUT_IS_SHARED template // non const version typename boost::lazy_enable_if_c< - (!clef::is_any_lazy::value) && (indexmaps::slicer::r_type::domain_type::rank!=0) + (!clef::is_any_lazy::value) && (indexmaps::slicer::r_type::domain_type::rank!=0) && !flags::is_const(OptionFlags) , result_of_call_as_view >::type // enable_if operator()(Args const & ... args) & { @@ -236,8 +238,7 @@ namespace triqs { namespace arrays { } /// Equivalent to make_view - //typename ISPViewType::type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag >::type - typename ISPViewType::type + typename ISPViewType::type operator()() const & { return *this; } typename ISPViewType::type diff --git a/triqs/utility/compiler_details.hpp b/triqs/utility/compiler_details.hpp index 9967b67f..686bad0b 100644 --- a/triqs/utility/compiler_details.hpp +++ b/triqs/utility/compiler_details.hpp @@ -21,13 +21,16 @@ #ifndef TRIQS_COMPILER_DETAILS_H #define TRIQS_COMPILER_DETAILS_H -#ifdef __GNUC__ +#if defined __GNUC__ || defined __clang__ #define restrict __restrict__ +#endif +#if defined __GNUC__ && ! defined __clang__ #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION < 40801 +#warning "gcc compiler" GCC_VERSION #define TRIQS_COMPILER_IS_OBSOLETE // we still accept gcc 4.6 and 4.7, but only the 4.8.1 and higher is a compliant c++11 #endif