Home | History | Annotate | Download | only in bits
      1 // The template and inlines for the -*- C++ -*- slice_array class.
      2 
      3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2009,
      4 // 2010  Free Software Foundation, Inc.
      5 //
      6 // This file is part of the GNU ISO C++ Library.  This library is free
      7 // software; you can redistribute it and/or modify it under the
      8 // terms of the GNU General Public License as published by the
      9 // Free Software Foundation; either version 3, or (at your option)
     10 // any later version.
     11 
     12 // This library is distributed in the hope that it will be useful,
     13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 // GNU General Public License for more details.
     16 
     17 // Under Section 7 of GPL version 3, you are granted additional
     18 // permissions described in the GCC Runtime Library Exception, version
     19 // 3.1, as published by the Free Software Foundation.
     20 
     21 // You should have received a copy of the GNU General Public License and
     22 // a copy of the GCC Runtime Library Exception along with this program;
     23 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     24 // <http://www.gnu.org/licenses/>.
     25 
     26 /** @file bits/slice_array.h
     27  *  This is an internal header file, included by other library headers.
     28  *  Do not attempt to use it directly. @headername{valarray}
     29  */
     30 
     31 // Written by Gabriel Dos Reis <Gabriel.Dos-Reis (at) DPTMaths.ENS-Cachan.Fr>
     32 
     33 #ifndef _SLICE_ARRAY_H
     34 #define _SLICE_ARRAY_H 1
     35 
     36 #pragma GCC system_header
     37 
     38 namespace std _GLIBCXX_VISIBILITY(default)
     39 {
     40 _GLIBCXX_BEGIN_NAMESPACE_VERSION
     41 
     42   /**
     43    * @addtogroup numeric_arrays
     44    * @{
     45    */
     46 
     47   /**
     48    *  @brief  Class defining one-dimensional subset of an array.
     49    *
     50    *  The slice class represents a one-dimensional subset of an array,
     51    *  specified by three parameters: start offset, size, and stride.  The
     52    *  start offset is the index of the first element of the array that is part
     53    *  of the subset.  The size is the total number of elements in the subset.
     54    *  Stride is the distance between each successive array element to include
     55    *  in the subset.
     56    *
     57    *  For example, with an array of size 10, and a slice with offset 1, size 3
     58    *  and stride 2, the subset consists of array elements 1, 3, and 5.
     59    */
     60   class slice
     61   {
     62   public:
     63     ///  Construct an empty slice.
     64     slice();
     65 
     66     /**
     67      *  @brief  Construct a slice.
     68      *
     69      *  @param  o  Offset in array of first element.
     70      *  @param  d  Number of elements in slice.
     71      *  @param  s  Stride between array elements.
     72      */
     73     slice(size_t, size_t, size_t);
     74 
     75     ///  Return array offset of first slice element.
     76     size_t start() const;
     77     ///  Return size of slice.
     78     size_t size() const;
     79     ///  Return array stride of slice.
     80     size_t stride() const;
     81 
     82   private:
     83     size_t _M_off;                      // offset
     84     size_t _M_sz;			// size
     85     size_t _M_st;			// stride unit
     86   };
     87 
     88   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     89   // 543. valarray slice default constructor
     90   inline
     91   slice::slice()
     92   : _M_off(0), _M_sz(0), _M_st(0) {}
     93 
     94   inline
     95   slice::slice(size_t __o, size_t __d, size_t __s)
     96   : _M_off(__o), _M_sz(__d), _M_st(__s) {}
     97 
     98   inline size_t
     99   slice::start() const
    100   { return _M_off; }
    101 
    102   inline size_t
    103   slice::size() const
    104   { return _M_sz; }
    105 
    106   inline size_t
    107   slice::stride() const
    108   { return _M_st; }
    109 
    110   /**
    111    *  @brief  Reference to one-dimensional subset of an array.
    112    *
    113    *  A slice_array is a reference to the actual elements of an array
    114    *  specified by a slice.  The way to get a slice_array is to call
    115    *  operator[](slice) on a valarray.  The returned slice_array then permits
    116    *  carrying operations out on the referenced subset of elements in the
    117    *  original valarray.  For example, operator+=(valarray) will add values
    118    *  to the subset of elements in the underlying valarray this slice_array
    119    *  refers to.
    120    *
    121    *  @param  Tp  Element type.
    122    */
    123   template<typename _Tp>
    124     class slice_array
    125     {
    126     public:
    127       typedef _Tp value_type;
    128 
    129       // _GLIBCXX_RESOLVE_LIB_DEFECTS
    130       // 253. valarray helper functions are almost entirely useless
    131 
    132       ///  Copy constructor.  Both slices refer to the same underlying array.
    133       slice_array(const slice_array&);
    134 
    135       ///  Assignment operator.  Assigns slice elements to corresponding
    136       ///  elements of @a a.
    137       slice_array& operator=(const slice_array&);
    138 
    139       ///  Assign slice elements to corresponding elements of @a v.
    140       void operator=(const valarray<_Tp>&) const;
    141       ///  Multiply slice elements by corresponding elements of @a v.
    142       void operator*=(const valarray<_Tp>&) const;
    143       ///  Divide slice elements by corresponding elements of @a v.
    144       void operator/=(const valarray<_Tp>&) const;
    145       ///  Modulo slice elements by corresponding elements of @a v.
    146       void operator%=(const valarray<_Tp>&) const;
    147       ///  Add corresponding elements of @a v to slice elements.
    148       void operator+=(const valarray<_Tp>&) const;
    149       ///  Subtract corresponding elements of @a v from slice elements.
    150       void operator-=(const valarray<_Tp>&) const;
    151       ///  Logical xor slice elements with corresponding elements of @a v.
    152       void operator^=(const valarray<_Tp>&) const;
    153       ///  Logical and slice elements with corresponding elements of @a v.
    154       void operator&=(const valarray<_Tp>&) const;
    155       ///  Logical or slice elements with corresponding elements of @a v.
    156       void operator|=(const valarray<_Tp>&) const;
    157       ///  Left shift slice elements by corresponding elements of @a v.
    158       void operator<<=(const valarray<_Tp>&) const;
    159       ///  Right shift slice elements by corresponding elements of @a v.
    160       void operator>>=(const valarray<_Tp>&) const;
    161       ///  Assign all slice elements to @a t.
    162       void operator=(const _Tp &) const;
    163       //        ~slice_array ();
    164 
    165       template<class _Dom>
    166         void operator=(const _Expr<_Dom, _Tp>&) const;
    167       template<class _Dom>
    168 	void operator*=(const _Expr<_Dom, _Tp>&) const;
    169       template<class _Dom>
    170 	void operator/=(const _Expr<_Dom, _Tp>&) const;
    171       template<class _Dom>
    172 	void operator%=(const _Expr<_Dom, _Tp>&) const;
    173       template<class _Dom>
    174 	void operator+=(const _Expr<_Dom, _Tp>&) const;
    175       template<class _Dom>
    176 	void operator-=(const _Expr<_Dom, _Tp>&) const;
    177       template<class _Dom>
    178 	void operator^=(const _Expr<_Dom, _Tp>&) const;
    179       template<class _Dom>
    180 	void operator&=(const _Expr<_Dom, _Tp>&) const;
    181       template<class _Dom>
    182 	void operator|=(const _Expr<_Dom, _Tp>&) const;
    183       template<class _Dom>
    184 	void operator<<=(const _Expr<_Dom, _Tp>&) const;
    185       template<class _Dom>
    186 	void operator>>=(const _Expr<_Dom, _Tp>&) const;
    187 
    188     private:
    189       friend class valarray<_Tp>;
    190       slice_array(_Array<_Tp>, const slice&);
    191 
    192       const size_t      _M_sz;
    193       const size_t      _M_stride;
    194       const _Array<_Tp> _M_array;
    195 
    196       // not implemented
    197       slice_array();
    198     };
    199 
    200   template<typename _Tp>
    201     inline
    202     slice_array<_Tp>::slice_array(_Array<_Tp> __a, const slice& __s)
    203     : _M_sz(__s.size()), _M_stride(__s.stride()),
    204       _M_array(__a.begin() + __s.start()) {}
    205 
    206   template<typename _Tp>
    207     inline
    208     slice_array<_Tp>::slice_array(const slice_array<_Tp>& a)
    209     : _M_sz(a._M_sz), _M_stride(a._M_stride), _M_array(a._M_array) {}
    210 
    211   //    template<typename _Tp>
    212   //    inline slice_array<_Tp>::~slice_array () {}
    213 
    214   template<typename _Tp>
    215     inline slice_array<_Tp>&
    216     slice_array<_Tp>::operator=(const slice_array<_Tp>& __a)
    217     {
    218       std::__valarray_copy(__a._M_array, __a._M_sz, __a._M_stride,
    219 			   _M_array, _M_stride);
    220       return *this;
    221     }
    222 
    223   template<typename _Tp>
    224     inline void
    225     slice_array<_Tp>::operator=(const _Tp& __t) const
    226     { std::__valarray_fill(_M_array, _M_sz, _M_stride, __t); }
    227 
    228   template<typename _Tp>
    229     inline void
    230     slice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
    231     { std::__valarray_copy(_Array<_Tp>(__v), _M_array, _M_sz, _M_stride); }
    232 
    233   template<typename _Tp>
    234   template<class _Dom>
    235     inline void
    236     slice_array<_Tp>::operator=(const _Expr<_Dom,_Tp>& __e) const
    237     { std::__valarray_copy(__e, _M_sz, _M_array, _M_stride); }
    238 
    239 #undef _DEFINE_VALARRAY_OPERATOR
    240 #define _DEFINE_VALARRAY_OPERATOR(_Op,_Name)				\
    241   template<typename _Tp>						\
    242     inline void								\
    243     slice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const	\
    244     {									\
    245       _Array_augmented_##_Name(_M_array, _M_sz, _M_stride, _Array<_Tp>(__v));\
    246     }									\
    247 									\
    248   template<typename _Tp>                                                \
    249     template<class _Dom>				                \
    250       inline void							\
    251       slice_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\
    252       {									\
    253 	  _Array_augmented_##_Name(_M_array, _M_stride, __e, _M_sz);	\
    254       }
    255 
    256 
    257 _DEFINE_VALARRAY_OPERATOR(*, __multiplies)
    258 _DEFINE_VALARRAY_OPERATOR(/, __divides)
    259 _DEFINE_VALARRAY_OPERATOR(%, __modulus)
    260 _DEFINE_VALARRAY_OPERATOR(+, __plus)
    261 _DEFINE_VALARRAY_OPERATOR(-, __minus)
    262 _DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
    263 _DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
    264 _DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
    265 _DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
    266 _DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
    267 
    268 #undef _DEFINE_VALARRAY_OPERATOR
    269 
    270   // @} group numeric_arrays
    271 
    272 _GLIBCXX_END_NAMESPACE_VERSION
    273 } // namespace
    274 
    275 #endif /* _SLICE_ARRAY_H */
    276