sl@0: // Copyright 2002 The Trustees of Indiana University. sl@0: sl@0: // Use, modification and distribution is subject to the Boost Software sl@0: // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: // Boost.MultiArray Library sl@0: // Authors: Ronald Garcia sl@0: // Jeremy Siek sl@0: // Andrew Lumsdaine sl@0: // See http://www.boost.org/libs/multi_array for documentation. sl@0: /* sl@0: * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. sl@0: */ sl@0: sl@0: // sl@0: // Trying to diagnose problems under visual sl@0: sl@0: #include "boost/config.hpp" sl@0: #include "boost/array.hpp" sl@0: #include "boost/limits.hpp" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: #include "std_log_result.h" sl@0: #define LOG_FILENAME_LINE __FILE__, __LINE__ sl@0: #endif sl@0: namespace dimtest sl@0: { sl@0: typedef int index; sl@0: } sl@0: sl@0: typedef std::size_t size_type; sl@0: sl@0: template sl@0: class index_range { sl@0: public: sl@0: sl@0: index_range() sl@0: { sl@0: start_ = from_start(); sl@0: finish_ = to_end(); sl@0: stride_ = 1; sl@0: degenerate_ = false; sl@0: } sl@0: sl@0: explicit index_range(Index pos) sl@0: { sl@0: start_ = pos; sl@0: finish_ = pos; sl@0: stride_ = 1; sl@0: degenerate_ = true; sl@0: } sl@0: sl@0: explicit index_range(Index start, Index finish, Index stride=1) sl@0: : start_(start), finish_(finish), stride_(stride), sl@0: degenerate_(start_ == finish_) sl@0: { } sl@0: sl@0: sl@0: // These are for chaining assignments to an index_range sl@0: index_range& start(Index s) { sl@0: start_ = s; sl@0: degenerate_ = (start_ == finish_); sl@0: return *this; sl@0: } sl@0: sl@0: index_range& finish(Index f) { sl@0: finish_ = f; sl@0: degenerate_ = (start_ == finish_); sl@0: return *this; sl@0: } sl@0: sl@0: index_range& stride(Index s) { stride_ = s; return *this; } sl@0: sl@0: Index start() const sl@0: { sl@0: return start_; sl@0: } sl@0: sl@0: Index get_start(Index low_index_range = 0) const sl@0: { sl@0: if (start_ == from_start()) sl@0: return low_index_range; sl@0: return start_; sl@0: } sl@0: sl@0: Index finish() const sl@0: { sl@0: return finish_; sl@0: } sl@0: sl@0: Index get_finish(Index high_index_range = 0) const sl@0: { sl@0: if (finish_ == to_end()) sl@0: return high_index_range; sl@0: return finish_; sl@0: } sl@0: sl@0: unsigned int size(Index recommended_length = 0) const sl@0: { sl@0: if ((start_ == from_start()) || (finish_ == to_end())) sl@0: return recommended_length; sl@0: else sl@0: return (finish_ - start_) / stride_; sl@0: } sl@0: sl@0: Index stride() const { return stride_; } sl@0: sl@0: bool is_ascending_contiguous() const sl@0: { sl@0: return (start_ < finish_) && is_unit_stride(); sl@0: } sl@0: sl@0: void set_index_range(Index start, Index finish, Index stride=1) sl@0: { sl@0: start_ = start; sl@0: finish_ = finish; sl@0: stride_ = stride; sl@0: } sl@0: sl@0: static index_range all() sl@0: { return index_range(from_start(), to_end(), 1); } sl@0: sl@0: bool is_unit_stride() const sl@0: { return stride_ == 1; } sl@0: sl@0: bool is_degenerate() const { return degenerate_; } sl@0: sl@0: index_range operator-(Index shift) const sl@0: { sl@0: return index_range(start_ - shift, finish_ - shift, stride_); sl@0: } sl@0: sl@0: index_range operator+(Index shift) const sl@0: { sl@0: return index_range(start_ + shift, finish_ + shift, stride_); sl@0: } sl@0: sl@0: Index operator[](unsigned i) const sl@0: { sl@0: return start_ + i * stride_; sl@0: } sl@0: sl@0: Index operator()(unsigned i) const sl@0: { sl@0: return start_ + i * stride_; sl@0: } sl@0: sl@0: // add conversion to std::slice? sl@0: sl@0: private: sl@0: static Index from_start() sl@0: { return (std::numeric_limits::min)(); } sl@0: sl@0: static Index to_end() sl@0: { return (std::numeric_limits::max)(); } sl@0: public: sl@0: Index start_, finish_, stride_; sl@0: bool degenerate_; sl@0: }; sl@0: sl@0: // Express open and closed interval end-points using the comparison sl@0: // operators. sl@0: sl@0: // left closed sl@0: template sl@0: inline index_range sl@0: operator<=(Index s, const index_range& r) sl@0: { sl@0: return index_range(s, r.finish(), r.stride()); sl@0: } sl@0: sl@0: // left open sl@0: template sl@0: inline index_range sl@0: operator<(Index s, const index_range& r) sl@0: { sl@0: return index_range(s + 1, r.finish(), r.stride()); sl@0: } sl@0: sl@0: // right open sl@0: template sl@0: inline index_range sl@0: operator<(const index_range& r, Index f) sl@0: { sl@0: return index_range(r.start(), f, r.stride()); sl@0: } sl@0: sl@0: // right closed sl@0: template sl@0: inline index_range sl@0: operator<=(const index_range& r, Index f) sl@0: { sl@0: return index_range(r.start(), f + 1, r.stride()); sl@0: } sl@0: sl@0: // sl@0: // range_list.hpp - helper to build boost::arrays for *_set types sl@0: // sl@0: sl@0: ///////////////////////////////////////////////////////////////////////// sl@0: // choose range list begins sl@0: // sl@0: sl@0: struct choose_range_list_n { sl@0: template sl@0: struct bind { sl@0: typedef boost::array type; sl@0: }; sl@0: }; sl@0: sl@0: struct choose_range_list_zero { sl@0: template sl@0: struct bind { sl@0: typedef boost::array type; sl@0: }; sl@0: }; sl@0: sl@0: sl@0: template sl@0: struct range_list_gen_helper { sl@0: typedef choose_range_list_n choice; sl@0: }; sl@0: sl@0: template <> sl@0: struct range_list_gen_helper<0> { sl@0: typedef choose_range_list_zero choice; sl@0: }; sl@0: sl@0: template sl@0: struct range_list_generator { sl@0: private: sl@0: typedef typename range_list_gen_helper::choice Choice; sl@0: public: sl@0: typedef typename Choice::template bind::type type; sl@0: }; sl@0: sl@0: // sl@0: // choose range list ends sl@0: ///////////////////////////////////////////////////////////////////////// sl@0: sl@0: // sl@0: // Index_gen.hpp stuff sl@0: // sl@0: sl@0: template sl@0: struct index_gen { sl@0: private: sl@0: typedef dimtest::index Index; sl@0: typedef size_type SizeType; sl@0: typedef index_range range; sl@0: public: sl@0: typedef typename range_list_generator::type range_list; sl@0: range_list ranges_; sl@0: sl@0: index_gen() { } sl@0: sl@0: template sl@0: explicit index_gen(const index_gen& rhs, sl@0: const index_range& range) sl@0: { sl@0: std::copy(rhs.ranges_.begin(),rhs.ranges_.end(),ranges_.begin()); sl@0: *ranges_.rbegin() = range; sl@0: } sl@0: sl@0: index_gen sl@0: operator[](const index_range& range) const sl@0: { sl@0: index_gen tmp; sl@0: std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin()); sl@0: *tmp.ranges_.rbegin() = range; sl@0: return tmp; sl@0: } sl@0: sl@0: index_gen sl@0: operator[](Index idx) const sl@0: { sl@0: index_gen tmp; sl@0: std::copy(ranges_.begin(),ranges_.end(),tmp.ranges_.begin()); sl@0: *tmp.ranges_.rbegin() = index_range(idx); sl@0: return tmp; sl@0: } sl@0: }; sl@0: sl@0: sl@0: template sl@0: void accept_gen(index_gen& indices) { sl@0: // do nothing sl@0: } sl@0: sl@0: template sl@0: class foo { }; sl@0: sl@0: class boo { sl@0: sl@0: public: sl@0: template sl@0: void operator[](index_gen& indices) { sl@0: sl@0: } sl@0: }; sl@0: sl@0: sl@0: template sl@0: void take_foo(foo& f) { } sl@0: sl@0: using namespace std; sl@0: int main() { sl@0: sl@0: index_gen<0,0> indices; sl@0: typedef index_range range; sl@0: sl@0: foo f; sl@0: take_foo(f); sl@0: sl@0: indices[range()][range()][range()]; sl@0: accept_gen(indices); sl@0: index_gen<0,0> index_g; sl@0: accept_gen(index_g); sl@0: index_gen<3,3> indices_3; sl@0: accept_gen(indices_3); sl@0: sl@0: boo b; sl@0: b[indices_3]; sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: testResultXml("dimtest"); sl@0: close_log_file(); sl@0: #endif sl@0: return 0; sl@0: }