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