diff --git a/doc/reference/c++/arrays/CMakeLists.txt b/doc/reference/c++/arrays/CMakeLists.txt index 65e6b28a..41ea718d 100644 --- a/doc/reference/c++/arrays/CMakeLists.txt +++ b/doc/reference/c++/arrays/CMakeLists.txt @@ -1,7 +1,6 @@ # Doxygen sources set_property(GLOBAL APPEND PROPERTY DOXYGEN_SOURCES ${TRIQS_SOURCE_DIR}/triqs/arrays/h5/simple_read_write.hpp - ${TRIQS_SOURCE_DIR}/triqs/arrays/h5/array_proxy.hpp ${TRIQS_SOURCE_DIR}/triqs/arrays/h5/array_stack.hpp ${TRIQS_SOURCE_DIR}/triqs/arrays/array.hpp ${TRIQS_SOURCE_DIR}/triqs/arrays/matrix.hpp diff --git a/test/triqs/arrays/h5_proxy.cpp.no-built b/test/triqs/arrays/h5_proxy.cpp.no-built deleted file mode 100644 index 1daf1de2..00000000 --- a/test/triqs/arrays/h5_proxy.cpp.no-built +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * - * 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 "./python_stuff.hpp" - -#include "./src/h5/array_proxy.hpp" -#include "./src/h5/simple_read_write.hpp" -#include -#include "./src/asserts.hpp" - - -using namespace triqs::arrays; - -template < class T> -void test(std::string filename, T init) { - - h5::H5File file( filename.c_str(), H5F_ACC_TRUNC ); - - const size_t N = 12, d= 2; - - array A(d,d+1), A2(d,d+1); - array A_stack_keep(N,d,d+1), A_stack_compare(N,d,d+1); - - array B(d), B2(d); - array B_stack_keep(N,d), B_stack_compare(N,d); - - - for (size_t u = 0; u M(6,6); - for (int u = 0; u<6; ++u) - for (int v = 0; v<6; ++v) - M(u,v) = 10*u + v; - - h5_write( file, "A", A_stack_keep); - h5_write( file, "A2", A_stack_keep); - h5_write( file, "B", B_stack_keep); - h5_write( file, "M", M); - - h5::array_proxy P( file, "A2"); - P (0,range(), range()) = T(2) *A; - - h5::array_proxy Pnew( file, "Z", make_shape(2,2,3) ); - - file.close(); - - // READING - // - h5::H5File file2 ( filename.c_str(), H5F_ACC_RDONLY ); - - h5::array_proxy AA( file2, "A"); - A_stack_compare = AA; - assert_all_close (A_stack_keep, A_stack_compare, 1.e-13); - std::cerr << "A_stack_compare = "<< A_stack_compare << std::endl; - - array A3(1,1); - for (size_t u = 0; u Pm( file2, "M"); - A3 = Pm; - std::cerr << "M from file with resize = "<< A3 << std::endl; - std::cerr << " ... should be = "<< M << std::endl; - assert_all_close (M, A3, 1.e-15); - - A3 = Pm( range(1,6,2), range (1,6,2)); - array_view V = M( range(1,6,2), range (1,6,2)); - std::cerr << "M from file with resize = "<< A3 << std::endl; - std::cerr << " ... should be = "<< V << std::endl; - assert_all_close (V, A3, 1.e-15); - - std::cerr << " ... done "<< std::endl; - - file2.close(); - -} - -int main(int argc, char **argv) { - - init_python_stuff(argc,argv); - - test("proxy_d.h5", 1.0 ); - test("proxy_c.h5", std::complex(1,2) ); - -} - diff --git a/triqs/arrays/h5/array_proxy.hpp b/triqs/arrays/h5/array_proxy.hpp deleted file mode 100644 index 2014dd1e..00000000 --- a/triqs/arrays/h5/array_proxy.hpp +++ /dev/null @@ -1,130 +0,0 @@ -/******************************************************************************* - * - * 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 . - * - ******************************************************************************/ -#ifndef TRIQS_ARRAYS_HDF5_ARRAY_PROXY_H -#define TRIQS_ARRAYS_HDF5_ARRAY_PROXY_H -#include "./array_proxy_impl.hpp" - -namespace triqs { namespace arrays { - namespace h5 { - - /// The array proxy - template - class array_proxy : TRIQS_CONCEPT_TAG_NAME(ImmutableArray), // WRONG ! IT does not yet implement [ ] - public sliceable_object < ValueType, - h5::index_system, - array_proxy_option, - Tag::h5_array_proxy, - ViewFactory, - indexmaps::slicer, - array_proxy > - { - public : - typedef ValueType value_type; - typedef std::pair< boost::shared_ptr ,std::string> storage_type; - static const bool T_is_complex = boost::is_complex::value; - typedef index_system< Rank, Rank_f> indexmap_type; - static const unsigned int rank = Rank; - - /// Opens a proxy on an existing array. The dataset must exists - template< class FileGroupType > - array_proxy ( FileGroupType file_group, std::string const & name) : - indexmap_ ( indexmap_type(file_group.openDataSet( name.c_str() ).getSpace(),T_is_complex) ) { - if (!h5::exists(file_group, name)) TRIQS_RUNTIME_ERROR<< " h5 : no dataset"<< name << " in file "; - storage_ = std::make_pair( boost::make_shared(file_group),name); - DataSet dataset = file_group.openDataSet( name.c_str() ); - try { if (T_is_complex) write_string_attribute(&dataset,"__complex__","1"); } - catch (...) {} // catch if the attribute already exists... - } - - /// Constructs a proxy on a new data set of the dimension of the domain D. The data must not exist. - template< class FileGroupType, class LengthType > - array_proxy ( FileGroupType file_group, std::string const & name_, LengthType L, bool overwrite = false) : - indexmap_ ( indexmap_type (L) ) - { - if (h5::exists(file_group, name_)) { - if (overwrite) file_group.unlink(name_.c_str()); - else TRIQS_RUNTIME_ERROR<< " h5 : dataset"<< name_ << " already exists in the file "; - } - storage_ = std::make_pair( boost::make_shared(file_group),name_); - DataSpace ds = indexmap_.template dataspace(); //(indexmap_type::rank_full, &indexmap_.lengths()[0], &indexmap_.strides()[0] ); - DataSet dataset = file_group.createDataSet( name_.c_str(), data_type_file(ValueType()), ds); - if (T_is_complex) write_string_attribute(&dataset,"__complex__","1"); - } - - /// Shallow copy - array_proxy(const array_proxy & X):indexmap_(X.indexmap()),storage_(X.storage_){} - - /// for slice construction - array_proxy (const indexmap_type & IM, const storage_type & ST): indexmap_(IM),storage_(ST){ } - - public: - indexmap_type const & indexmap() const {return indexmap_;} - storage_type const & storage() const {return storage_;} - storage_type & storage() {return storage_;} - const H5::CommonFG * file_group() const { return storage_.first.get();} - std::string const & name() const { return storage_.second;} - - typedef typename indexmap_type::domain_type domain_type; - domain_type const & domain() const { return indexmap_.domain();} - - typedef typename domain_type::index_value_type shape_type; - shape_type const & shape() const { return domain().lengths();} - - size_t num_elements() const { return domain().number_of_elements();} - bool is_empty() const { return this->num_elements()==0;} - - template< typename ISP>// put in the file... - void operator=(ISP const & X) { - try { - BOOST_AUTO(C, make_const_cache(X, Option::C())); - //typename result_of::cache::type C(X); - DataSet dataset = file_group()->openDataSet( name().c_str() ); - dataset.write( h5::data(C.view()), h5::data_type_mem(C.view()),h5::data_space(C.view()),indexmap().template dataspace()); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } - - template // from the file to the array or the array_view... - friend void triqs_arrays_assign_delegation (LHS & lhs, array_proxy const & rhs) { - static_assert((is_amv_value_or_view_class::value), "LHS is not a value or a view class "); - h5::resize_or_check(lhs, rhs.indexmap().domain().lengths()); - try { - DataSet dataset = rhs.file_group()->openDataSet( rhs.name().c_str() ); - BOOST_AUTO(C, make_cache(lhs, Option::C() )); - //typename result_of::cache::type C(lhs); - dataset.read( h5::data(C.view()), h5::data_type_mem(C.view()), h5::data_space(C.view()), - rhs.indexmap().template dataspace() ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - } - - protected: - indexmap_type indexmap_; - storage_type storage_; - - }; - }// namesapce h5 - - template < class V, int R, int Rf > - struct ViewFactory< V, R, h5::array_proxy_option, Tag::h5_array_proxy > { typedef h5::array_proxy type; }; -}} -#endif - diff --git a/triqs/arrays/h5/array_proxy_impl.hpp b/triqs/arrays/h5/array_proxy_impl.hpp deleted file mode 100644 index 5792c089..00000000 --- a/triqs/arrays/h5/array_proxy_impl.hpp +++ /dev/null @@ -1,160 +0,0 @@ -/******************************************************************************* - * - * 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 . - * - ******************************************************************************/ -#ifndef TRIQS_ARRAYS_HDF5_ARRAY_PROXY_IMPL_H -#define TRIQS_ARRAYS_HDF5_ARRAY_PROXY_IMPL_H -//#define TRIQS_ARRAYS_DEBUG_H5_SLICE - -#include "../indexmaps/cuboid/domain.hpp" -#include "./group_or_file.hpp" -#include "../impl/sliceable_object.hpp" -#include "../impl/tuple_tools.hpp" -#include -#include - -namespace triqs { namespace arrays { - - namespace h5 { template struct array_proxy_option {}; } - - namespace Option { - template struct Im_Opt_2_Opt > { typedef h5::array_proxy_option type;}; - } - - namespace h5 { - - template - class index_system { - - public : - static const unsigned int rank= Rank, rank_full = Rank_full; - typedef mini_vector v_type; - typedef mini_vector v_type_full; - typedef indexmaps::cuboid::domain domain_type; - domain_type const & domain() const { return mydomain;} - - index_system (v_type_full const & total_lengths_) { - total_lens_ = total_lengths_; lens_= total_lengths_; - for (size_t i =0; i DataSpace dataspace() const { return h5::dataspace_from_LS (total_lens_, lens_,stri_,off_); } - size_t size() const { size_t _size = 1; for (size_t i =0; i total_lengths() const { return this->total_lens_;} - mini_vector lengths() const { return this->lens_;} - mini_vector strides() const { return this->stri_;} - - private: - mini_vector lens_, off_, stri_; - v_type dims; - v_type_full total_lens_; - domain_type mydomain; - }; - - namespace slicer_impl { - - template inline void _check_BC ( int N, int ind, size_t B) { } - template <> inline void _check_BC (int N, int ind, size_t B) { - bool cond = (ind >= 0) && (ind < int(B)); // fix this int ... - if (!cond) TRIQS_ARRAYS_KEY_ERROR << " index "< struct slice_calc { - - typedef mini_vector const & i_type; - typedef mini_vector & o_type; - typedef mini_vector & os_type; - - template< typename ArgsTuple> - static void invoke(i_type li, i_type si, os_type lo_c, o_type lo, o_type so, o_type offset, ArgsTuple const & args ) { - const int dP = boost::is_base_of::type, range >::type::value ; - one_step(li[N], si[N],lo[N],so[N], offset[N] ,boost::tuples::get(args)); - lo_c[P] = lo[N]; - slice_calc::invoke(li,si,lo_c,lo,so, offset, args); - } - - static void one_step(size_t li, size_t si, size_t & lo, size_t & so, size_t & offset, size_t R){ - _check_BC (N, R, li); - offset = R; lo =1; so= 1; - } - - static void one_step(size_t li, size_t si, size_t & lo, size_t & so, size_t & offset, range R){ - _check_BC (N, R.first(),li); - _check_BC (N, (R.last()==-1 ? li : R.last()) -1 ,li); - lo = ((R.last()==-1 ? li : R.last()) - R.first() + R.step()-1 )/R.step() ; // python behaviour - so = R.step(); offset = R.first() ; - } - }; - // stop the recursion - template struct slice_calc : slice_calc { - template static void invoke(T1,T2,T3,T4,T5,T6,T7 ) {} - }; - - }//namespace slicer_impl - } // h5 - - namespace indexmaps { - - template - struct slicer < h5::index_system, ArgsTuple> { - - static const unsigned int len = boost::tuples::length::value; - static_assert(len>=R, "Too few arguments in slice"); - static_assert(len<=R, "Too many arguments in slice"); - static_assert( (R==Rf), "Can not slice array_proxy twice (not implemented)"); - - static const unsigned int R2 = R - TupleTools::CountHowManyInt::value; - typedef h5::index_system< R2, Rf> return_type; - - static return_type invoke ( h5::index_system const & X, ArgsTuple args) { - mini_vector newdims; - mini_vector newoffset, newlengths, newstrides; - h5::slicer_impl::slice_calc::invoke(X.lengths(),X.strides(),newdims, newlengths,newstrides, newoffset, args); -#ifdef TRIQS_ARRAYS_DEBUG_H5_SLICE - std::cerr<<"-----------------------------------------------"< struct slicer < h5::index_system, boost::tuple<> > { typedef h5::index_system< R,Rf> return_type;}; - } - -}} -#endif - diff --git a/triqs/arrays/h5/common.hpp.old b/triqs/arrays/h5/common.hpp.old deleted file mode 100644 index 42016769..00000000 --- a/triqs/arrays/h5/common.hpp.old +++ /dev/null @@ -1,230 +0,0 @@ -/******************************************************************************* - * - * 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 . - * - ******************************************************************************/ -#ifndef TRIQS_ARRAYS_H5_COMMON_H -#define TRIQS_ARRAYS_H5_COMMON_H - -#include -#include "hdf5_hl.h" -#include "../cache.hpp" -#include -#include - -template std::string get_triqs_hdf5_data_scheme(T const & ) { return "";} - -namespace triqs { namespace arrays { namespace h5 { - using namespace H5; - // conversion of C type to HDF5 native - inline PredType native_type_from_C(char) { return PredType::NATIVE_CHAR; } - inline PredType native_type_from_C(signed char) { return PredType::NATIVE_SCHAR; } - inline PredType native_type_from_C(unsigned char) { return PredType::NATIVE_UCHAR; } - inline PredType native_type_from_C(short) { return PredType::NATIVE_SHORT; } - inline PredType native_type_from_C(unsigned short) { return PredType::NATIVE_USHORT; } - inline PredType native_type_from_C(int) { return PredType::NATIVE_INT; } - inline PredType native_type_from_C(unsigned) { return PredType::NATIVE_UINT; } - inline PredType native_type_from_C(long) { return PredType::NATIVE_LONG; } - inline PredType native_type_from_C(unsigned long) { return PredType::NATIVE_ULONG; } - inline PredType native_type_from_C(long long) { return PredType::NATIVE_LLONG; } - inline PredType native_type_from_C(unsigned long long) { return PredType::NATIVE_ULLONG; } - inline PredType native_type_from_C(float) { return PredType::NATIVE_FLOAT; } - inline PredType native_type_from_C(double) { return PredType::NATIVE_DOUBLE; } - inline PredType native_type_from_C(long double) { return PredType::NATIVE_LDOUBLE; } - inline PredType native_type_from_C(bool) { return PredType::NATIVE_SCHAR; } - inline PredType native_type_from_C(std::string) { return PredType::C_S1; } - - // conversion of C type to HDF5 native - // NEED TO CHANGE THIS ? It is not standard... We should fix a standard or have a trait - inline PredType h5_type_from_C(char) { return PredType::NATIVE_CHAR; } - inline PredType h5_type_from_C(signed char) { return PredType::NATIVE_SCHAR; } - inline PredType h5_type_from_C(unsigned char) { return PredType::NATIVE_UCHAR; } - inline PredType h5_type_from_C(short) { return PredType::NATIVE_SHORT; } - inline PredType h5_type_from_C(unsigned short) { return PredType::NATIVE_USHORT; } - inline PredType h5_type_from_C(int) { return PredType::NATIVE_INT; } - inline PredType h5_type_from_C(unsigned) { return PredType::NATIVE_UINT; } - inline PredType h5_type_from_C(long) { return PredType::NATIVE_LONG; } - inline PredType h5_type_from_C(unsigned long) { return PredType::NATIVE_ULONG; } - inline PredType h5_type_from_C(long long) { return PredType::NATIVE_LLONG; } - inline PredType h5_type_from_C(unsigned long long) { return PredType::NATIVE_ULLONG; } - inline PredType h5_type_from_C(float) { return PredType::NATIVE_FLOAT; } - inline PredType h5_type_from_C(double) { return PredType::NATIVE_DOUBLE; } - inline PredType h5_type_from_C(long double) { return PredType::NATIVE_LDOUBLE; } - inline PredType h5_type_from_C(bool) { return PredType::NATIVE_SCHAR; } - inline PredType h5_type_from_C(std::string) { return PredType::C_S1; } - - // If it is complex return T else T - template struct remove_complex { typedef T type;}; - template struct remove_complex > { typedef T type;}; - - template - PredType data_type_mem ( ArrayType const & A) { - return native_type_from_C(typename remove_complex::type()); - } - - template - PredType data_type_mem_scalar ( S const & A) { - return native_type_from_C(typename remove_complex::type()); - } - - // the type of data to put in the file_or_group - template - PredType data_type_file ( V const & ) { return h5_type_from_C(typename remove_complex::type());} - - // the pointer on the start of data - template - TYPE_DISABLE_IF ( void *, boost::is_complex ) - data ( ArrayType const & A) { return &(A.storage()[0]);} - - template - TYPE_ENABLE_IF ( void *, boost::is_complex ) - data ( ArrayType const & A) { - typedef typename ArrayType::value_type::value_type T; - std::complex * p = &(A.storage()[0]); - return reinterpret_cast(p); - } - - // dataspace from lengths and strides. Correct for the complex. strides must be >0 - template - H5::DataSpace dataspace_from_LS ( - mini_vector const & Ltot, - mini_vector const & L, - mini_vector const & S, - mini_vector const & offset = mini_vector() ) { -#ifdef TRIQS_ARRAYS_DEBUG_H5_SLICE - std::cerr << "total lens in dataspace_from_LS"<< Ltot.to_string() << std::endl ; - std::cerr << "lens in dataspace_from_LS"<< L.to_string() << std::endl ; - std::cerr << "Strides in dataspace_from_LS "<< S.to_string() << std::endl ; - std::cerr << "offset in dataspace_from_LS"<< offset.to_string() << std::endl ; -#endif - static const unsigned int rank = R + (IsComplex ? 1 : 0); - hsize_t totdimsf[rank], dimsf [rank], stridesf[rank], offsetf[rank]; // dataset dimensions - for (size_t u=0; u - H5::DataSpace data_space ( ArrayType const & A) { - static const unsigned int R = ArrayType::rank; - mini_vector S; - mini_vector const & S1 ( A.indexmap().strides() ); - for (size_t u=0; u::value; - return dataspace_from_LS ( A.indexmap().domain().lengths(),A.indexmap().domain().lengths(), S); - } - - /******************** resize or check the size ****************************************************/ - - template ENABLE_IF(is_amv_value_class) - resize_or_check ( A & a, mini_vector const & dimsf ) { a.resize( indexmaps::cuboid::domain_t( dimsf)); } - - template ENABLE_IF(is_amv_view_class) - resize_or_check ( A const & a, mini_vector const & dimsf ) { - if (a.indexmap().domain().lengths() != dimsf) TRIQS_RUNTIME_ERROR<<"Dimension error : the view can not be resized : " - << "\n in file : "<< dimsf.to_string() - << "\n in view : "<createAttribute(name.c_str(), strdatatype, attr_dataspace); - //myatt_in.write(strdatatype, strwritebuf); - myatt_in.write(strdatatype, (void *)(value.c_str())); - } - - /****************** Read string attribute *********************************************/ - - /// Return the attribute name of obj, and "" if the attribute does not exist. - inline std::string read_string_attribute (H5::H5Object const * obj, std::string name ) { - std::string value =""; - Attribute attr; - if (H5LTfind_attribute(obj -> getId(), name.c_str() )==0) return value;// not present - // can not find how to get the size with hl. Using full interface - //herr_t err2 = H5LTget_attribute_string(gr.getId(), x.c_str(), name.c_str() , &(buf.front()) ) ; - //if (err2 < 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0"; - //value.append( &(buf.front()) ); - try { attr= obj->openAttribute(name.c_str());} - catch (H5::AttributeIException) { return value;} - try { - DataSpace dataspace = attr.getSpace(); - int rank = dataspace.getSimpleExtentNdims(); - if (rank != 0) TRIQS_RUNTIME_ERROR << "Reading a string attribute and got rank !=0"; - size_t size = attr.getStorageSize(); - StrType strdatatype(PredType::C_S1, size); - std::vector buf(size+1, 0x00); - attr.read(strdatatype, (void *)(&buf[0])); - value.append( &(buf.front()) ); - } - TRIQS_ARRAYS_H5_CATCH_EXCEPTION; - return value; - } - - /****************** Read/Write the special TRIQS_HDF5_data_scheme attribute *********************************************/ - - template - inline void write_triqs_hdf5_data_scheme( H5::Group g, T const & obj) { - write_string_attribute( &g, "TRIQS_HDF5_data_scheme" , get_triqs_hdf5_data_scheme(obj).c_str() ) ; - // herr_t err = H5LTset_attribute_string(F.getId(), subgroup_name.c_str(), "TRIQS_HDF5_data_scheme" , get_triqs_hdf5_data_scheme(p).c_str() ) ; - } - - inline std::string read_triqs_hdf5_data_scheme( H5::Group g) { return read_string_attribute( &g, "TRIQS_HDF5_data_scheme") ; } - - - /****************** WRITE attribute *********************************************/ - - //inline void write_triqs_data_scheme ( H5::H5Object const & grp, std::string obj_name, std::string attr_name, std::string triqs_data_scheme ) { - // herr_t err = H5LTset_attribute_string(grp.getId(),obj_name.c_str(),attr_name.c_str(), , value.c_str() ) ; - // if (err<0) TRIQS_RUNTIME_ERROR << "Error in setting attribute "<< name << " to " << value; - // } - - - -}}} -#endif