📄 dense1d.h
字号:
//// Copyright 1997, 1998, 1999 University of Notre Dame.// Authors: Andrew Lumsdaine, Jeremy G. Siek, Lie-Quan Lee//// This file is part of the Matrix Template Library//// You should have received a copy of the License Agreement for the// Matrix Template Library along with the software; see the// file LICENSE. If not, contact Office of Research, University of Notre// Dame, Notre Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//////===========================================================================#ifndef MTL_DENSE1D_H#define MTL_DENSE1D_H#include <vector>#include <utility>#include "mtl/refcnt_ptr.h"#include "mtl/dense_iterator.h"#include "mtl/reverse_iter.h"#include "mtl/light1D.h"#include "mtl/mtl_config.h"#include "mtl/matrix_traits.h"#include "mtl/scaled1D.h"#include "mtl/mtl_exception.h"/*#include "mtl/concept_checks.h"*//** @name 1 Dimensional Containers and Adaptors The MTL 1-dimensional containers can be used as vectors and also to compose 2-dimensional containers. There are also 2 adaptors, the scaled1D and strided1D classes. The adaptors are not meant to be used directly. Instead they are used to implement the scaled() and strided() functions for wrapping up MTL function arguments. One can always access the row and columns vectors of a matrix, which are first-class vectors in MTL. They can be used with the MTL vector algorithms. This is demonstrated in several of the example programs. *//* Think about having a non-zero starting index note, do not use std::vector any more because it puts all kinds of checks into the operator[] or find out how to turn off the checking. */namespace mtl { //: Dense 1-D Container //!category: containers //!component: type // // This is the primary class that you will need to use as a Vector. // This class uses the STL <tt>vector</tt> for its implementation. // The <TT>dense1D</TT> class serves as a handle // to the <TT>vector</TT>. The MTL algorithms assume that the // vector and matrix arguments are handles, and will not // work with the STL style containers. // For interoperability, one can create a <TT>dense1D</TT> // from pre-existing memory. In this case, the mtl reference // counting does not delete the memory. // //!definition: dense1D.h //!tparam: RepType - the underlying representation //!models: Vectortemplate <class T, int NN = 0>class dense1D { /* CLASS_REQUIRES(T, Assignable);*/ typedef dense1D<T,NN> self; typedef std::vector<T> rep_type; /* typedef RepType rep_type; */ typedef refcnt_ptr< rep_type > rep_ptr;public: /**@name Type Definitions */ enum { N = NN }; /* enum { dimension = 1 }; */ typedef oned_tag dimension; //: The sparsity tag typedef dense_tag sparsity; //: The scaled type of this container //!wheredef: Scalable typedef scaled1D< self > scaled_type; //: The value type //!wheredef: Container typedef typename rep_type::value_type value_type; //: The reference type //!wheredef: Container typedef typename rep_type::reference reference; //: blah //!wheredef: Container typedef typename rep_type::const_reference const_reference;#if !defined( _MSVCPP_ ) //: blah //!wheredef: Container typedef typename rep_type::pointer pointer;#else typedef value_type* pointer;#endif //: blah //!wheredef: Container typedef typename rep_type::size_type size_type; //: blah //!wheredef: Container typedef typename rep_type::difference_type difference_type; //: blah //!wheredef: Container#if !defined( _MSVCPP_ ) typedef dense_iterator<typename rep_type::iterator> iterator; //: blah //!wheredef: Container typedef dense_iterator<typename rep_type::const_iterator> const_iterator;#else typedef dense_iterator<typename rep_type::value_type, 0> iterator; typedef dense_iterator<typename rep_type::value_type, 1> const_iterator;#endif //: blah //!wheredef: Reversible Container typedef reverse_iter<iterator> reverse_iterator; //: blah //!wheredef: Reversible Container typedef reverse_iter<const_iterator> const_reverse_iterator; typedef light1D<value_type> subrange_type; typedef std::pair<size_type,size_type> range_type; /**@name Constructors */ typedef self Vec; typedef size_type Vec_size_type; typedef difference_type Vec_difference_type; typedef iterator Vec_iterator; typedef const_iterator Vec_const_iterator; typedef value_type Vec_value_type;#if 1 class IndexArray { public: typedef Vec_size_type size_type; typedef Vec_difference_type difference_type; typedef Vec_size_type value_type; class iterator { public: typedef size_type value_type; typedef size_type reference; typedef size_type* pointer; typedef Vec_difference_type difference_type; typedef typename std::iterator_traits<Vec_iterator>::iterator_category iterator_category; iterator(Vec_iterator iter, Vec_iterator e) : i(iter), end(e) { while (*i == Vec_value_type(0)) ++i; } reference operator*() const { return i.index(); } iterator& operator++() { ++i; while (*i == Vec_value_type(0) && i != end) ++i; return *this; } iterator operator++(int) { iterator t = *this; ++(*this); return t; } iterator& operator--() { --i; while (*i == Vec_value_type(0) && i != end) --i; return *this; } iterator operator--(int) { iterator t = *this; --(*this); return t; } difference_type operator-(const iterator& x) const { return i - x.i; } bool operator==(const iterator& x) const { return i == x.i; } bool operator!=(const iterator& x) const { return i != x.i; } bool operator<(const iterator& x) const { return i < x.i; } Vec_iterator i; Vec_iterator end; }; class const_iterator { public: typedef size_type value_type; typedef size_type reference; typedef size_type* pointer; typedef Vec_difference_type difference_type; typedef typename std::iterator_traits<Vec_iterator>::iterator_category iterator_category; const_iterator(Vec_const_iterator iter, Vec_const_iterator e) : i(iter), end(e) { while (*i == Vec_value_type(0) && i != end) ++i; } reference operator*() const { return i.index(); } const_iterator& operator++() { ++i; while (*i == Vec_value_type(0) && i != end) ++i; return *this; } const_iterator operator++(int) { const_iterator t = *this; ++(*this); return t; } const_iterator& operator--() { --i; while (*i == Vec_value_type(0)) --i; return *this; } const_iterator operator--(int) { const_iterator t = *this; --(*this); return t; } difference_type operator-(const const_iterator& x) const { return i - x.i; } bool operator==(const const_iterator& x) const { return i == x.i; } bool operator!=(const const_iterator& x) const { return i != x.i; } bool operator<(const const_iterator& x) const { return i < x.i; } Vec_const_iterator i; Vec_const_iterator end; }; inline IndexArray(const Vec& v) : vec((Vec*)&v) { } inline iterator begin() { return iterator(vec->begin(), vec->end()); } inline iterator end() { return iterator(vec->end(), vec->end()); } inline const_iterator begin() const{ return const_iterator(((const Vec*)vec)->begin(), ((const Vec*)vec)->end()); } inline const_iterator end() const { return const_iterator(((const Vec*)vec)->end(), ((const Vec*)vec)->end()); } size_type size() const { size_type s = 0; Vec_const_iterator i; for (i = ((const Vec*)vec)->begin(); i != ((const Vec*)vec)->end(); ++i) if (*i != Vec_value_type(0)) ++s; return s; } Vec* vec; }; typedef IndexArray IndexArrayRef;#else /* JGS, problem. IndexArray introduces several requirements on value type that interfere with using dense1D as the backbone for array2D */ typedef self IndexArray; typedef self IndexArrayRef;#endif //: Default Constructor //!wheredef: Container inline dense1D() : rep(new rep_type()), first(0) { } //: Non-Initializing Constructor not very standard :( //!wheredef: Sequence inline dense1D(size_type n) : rep(new rep_type(n)), first(0) { } /* JGS Don't ever try to fold these two constructors into one with a * defualt. The array2D depends on being able to construct without * initialization otherwise all vectors in the array2D end up being * handles to the same vector */ //: Initializing Constructor //!wheredef: Sequence inline dense1D(size_type n, const value_type& init) : rep(new rep_type(n,init)), first(0) { } //: Copy Constructor (shallow copy) //!wheredef: ContainerRef inline dense1D(const self& x) : rep(x.rep), first(x.first) { } //: The destructor. //!wheredef: Container inline ~dense1D() { } //: Assignment Operator (shallow copy) //!wheredef: AssignableRef inline self& operator=(const self& x) { rep = x.rep; first = x.first; return *this; } /* Access Methods */ /* Iterator Access Methods */ //: Return an iterator pointing to the beginning of the vector //!wheredef: Container inline iterator begin() { return iterator(rep->begin(),0, first); } //: Return an iterator pointing past the end of the vector //!wheredef: Container inline iterator end() { return iterator(rep->begin(), rep->size(), first); } //: Return a const iterator pointing to the begining of the vector //!wheredef: Container inline const_iterator begin() const { return const_iterator(rep->begin(), 0, first); } //: Return a const iterator pointing past the end of the vector //!wheredef: Container inline const_iterator end() const{ return const_iterator(rep->begin(), rep->size(), first); } //: Return a reverse iterator pointing to the last element of the vector //!wheredef: Reversible Container inline reverse_iterator rbegin() { return reverse_iterator(end()); } //: Return a reverse iterator pointing past the end of the vector //!wheredef: Reversible Container inline reverse_iterator rend() { return reverse_iterator(begin()); } //: Return a const reverse iterator pointing to the last element //!wheredef: Reversible Container inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } //: Return a const reverse iterator pointing past the end of the vector //!wheredef: Reversible Container inline const_reverse_iterator rend() const{ return const_reverse_iterator(begin()); } /* Element Access Methods */ //: Return a reference to the element with index i //!wheredef: Random Access Container inline reference operator[](size_type i) MTL_THROW_ASSERTION { MTL_ASSERT(i - first < size(), "dense1D::operator[]"); return (*rep)[i - first]; } //: Return a const reference to the element with index i //!wheredef: Random Access Container inline const_reference operator[](size_type i) const MTL_THROW_ASSERTION { MTL_ASSERT(i - first < size(), "dense1D::operator[]"); return (*rep)[i - first]; } inline subrange_type operator()(range_type r) const MTL_THROW_ASSERTION { return subrange_type(data() + r.first - first, r.second - r.first, 0); } inline subrange_type operator()(size_type s, size_type f) const MTL_THROW_ASSERTION { return subrange_type(const_cast<value_type*>(data()) + s - first, f - s, 0); } /* Size Methods */ //: Return the size of the vector //!wheredef: Container inline size_type size() const { return rep->size(); } //: Return the number of non-zeroes inline size_type nnz() const { return rep->size(); } //: inline void resize(size_type n) { rep->resize(n); } inline void resize(size_type n, const T& x) { rep->resize(n, x); } //: inline size_type capacity() const { return rep->capacity(); } //: void reserve(size_type n) { rep->reserve(n); } //: Raw Memory Access inline const value_type* data() const { return &(*rep)[0]; } inline pointer data() { return &(*rep)[0]; } //: //!wheredef: Container iterator insert (iterator position, const value_type& x = value_type()) { return iterator(rep->insert(position.base(), x), position.index()+1); // JGS, not sure about what to do with the index here } void insert (iterator position, size_type n, const value_type& x = value_type()) { rep->insert(position.base(), n, x); /* return iterator(, position.index()+n); JGS, not sure about what to do with the index here */ } void push_back(const value_type& x) { rep->push_back(x); } inline IndexArrayRef nz_struct() const { return IndexArrayRef(*this); } self& adjust_index(size_type delta) { first += delta; return *this; } protected: rep_ptr rep; size_type first;};} /* namespace mtl */#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -