1 //=================================================================================================
2 /*!
3 //  \file blaze/math/expressions/DVecMapExpr.h
4 //  \brief Header file for the dense vector map expression
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DVECMAPEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECMAPEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
46 #include <blaze/math/constraints/DenseVector.h>
47 #include <blaze/math/constraints/RequiresEvaluation.h>
48 #include <blaze/math/constraints/TransposeFlag.h>
49 #include <blaze/math/Exception.h>
50 #include <blaze/math/expressions/Computation.h>
51 #include <blaze/math/expressions/DenseVector.h>
52 #include <blaze/math/expressions/Forward.h>
53 #include <blaze/math/expressions/VecMapExpr.h>
54 #include <blaze/math/Functors.h>
55 #include <blaze/math/shims/Serial.h>
56 #include <blaze/math/SIMD.h>
57 #include <blaze/math/traits/AddTrait.h>
58 #include <blaze/math/traits/DivTrait.h>
59 #include <blaze/math/traits/MapTrait.h>
60 #include <blaze/math/traits/MultTrait.h>
61 #include <blaze/math/traits/SubTrait.h>
62 #include <blaze/math/typetraits/HasLoad.h>
63 #include <blaze/math/typetraits/IsAligned.h>
64 #include <blaze/math/typetraits/IsComputation.h>
65 #include <blaze/math/typetraits/IsExpression.h>
66 #include <blaze/math/typetraits/IsPadded.h>
67 #include <blaze/math/typetraits/IsPaddingEnabled.h>
68 #include <blaze/math/typetraits/IsScalar.h>
69 #include <blaze/math/typetraits/IsSIMDEnabled.h>
70 #include <blaze/math/typetraits/RequiresEvaluation.h>
71 #include <blaze/math/typetraits/UnderlyingScalar.h>
72 #include <blaze/system/HostDevice.h>
73 #include <blaze/system/Inline.h>
74 #include <blaze/system/MacroDisable.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/FunctionTrace.h>
78 #include <blaze/util/IntegralConstant.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/Types.h>
81 #include <blaze/util/typetraits/IsNumeric.h>
82 #include <blaze/util/typetraits/IsSame.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 //  CLASS DVECMAPEXPR
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
94 /*!\brief Expression object for the dense vector map() function.
95 // \ingroup dense_vector_expression
96 //
97 // The DVecMapExpr class represents the compile time expression for the evaluation of a custom
98 // operation on each element of a dense vector via the map() function.
99 */
100 template< typename VT  // Type of the dense vector
101         , typename OP  // Type of the custom operation
102         , bool TF >    // Transpose flag
103 class DVecMapExpr
104    : public VecMapExpr< DenseVector< DVecMapExpr<VT,OP,TF>, TF > >
105    , private Computation
106 {
107  private:
108    //**Type definitions****************************************************************************
109    using RT = ResultType_t<VT>;  //!< Result type of the dense vector expression.
110    using ET = ElementType_t<VT>;  //!< Element type of the dense vector expression.
111    using RN = ReturnType_t<VT>;  //!< Return type of the dense vector expression.
112    //**********************************************************************************************
113 
114    //**Serial evaluation strategy******************************************************************
115    //! Compilation switch for the serial evaluation strategy of the map expression.
116    /*! The \a useAssign compile time constant expression represents a compilation switch for
117        the serial evaluation strategy of the map expression. In case the given dense vector
118        expression of type \a VT is a computation expression and requires an intermediate
119        evaluation, \a useAssign will be set to 1 and the map expression will be evaluated
120        via the \a assign function family. Otherwise \a useAssign will be set to 0 and the
121        expression will be evaluated via the subscript operator. */
122    static constexpr bool useAssign = ( IsComputation_v<VT> && RequiresEvaluation_v<VT> );
123 
124    /*! \cond BLAZE_INTERNAL */
125    //! Helper variable template for the explicit application of the SFINAE principle.
126    template< typename VT2 >
127    static constexpr bool UseAssign_v = useAssign;
128    /*! \endcond */
129    //**********************************************************************************************
130 
131    //**Parallel evaluation strategy****************************************************************
132    /*! \cond BLAZE_INTERNAL */
133    //! Helper variable template for the explicit application of the SFINAE principle.
134    /*! This variable template is a helper for the selection of the parallel evaluation strategy.
135        In case either the target vector or the dense vector operand is not SMP assignable and
136        the vector operand requires an intermediate evaluation, the variable is set to 1 and the
137        expression specific evaluation strategy is selected. Otherwise the variable is set to 0
138        and the default strategy is chosen. */
139    template< typename VT2 >
140    static constexpr bool UseSMPAssign_v =
141       ( ( !VT2::smpAssignable || !VT::smpAssignable ) && useAssign );
142    /*! \endcond */
143    //**********************************************************************************************
144 
145  public:
146    //**Type definitions****************************************************************************
147    //! Type of this DVecMapExpr instance.
148    using This = DVecMapExpr<VT,OP,TF>;
149 
150    //! Base type of this DVecMapExpr instance.
151    using BaseType = VecMapExpr< DenseVector<This,TF> >;
152 
153    using ResultType    = MapTrait_t<RT,OP>;            //!< Result type for expression template evaluations.
154    using TransposeType = TransposeType_t<ResultType>;  //!< Transpose type for expression template evaluations.
155    using ElementType   = ElementType_t<ResultType>;    //!< Resulting element type.
156 
157    //! Return type for expression template evaluations.
158    using ReturnType = decltype( std::declval<OP>()( std::declval<RN>() ) );
159 
160    //! Data type for composite expression templates.
161    using CompositeType = If_t< useAssign, const ResultType, const DVecMapExpr& >;
162 
163    //! Composite data type of the dense vector expression.
164    using Operand = If_t< IsExpression_v<VT>, const VT, const VT& >;
165 
166    //! Data type of the custom unary operation.
167    using Operation = OP;
168    //**********************************************************************************************
169 
170    //**ConstIterator class definition**************************************************************
171    /*!\brief Iterator over the elements of the dense vector map expression.
172    */
173    class ConstIterator
174    {
175     public:
176       //**Type definitions*************************************************************************
177       using IteratorCategory = std::random_access_iterator_tag;  //!< The iterator category.
178       using ValueType        = ElementType;                      //!< Type of the underlying elements.
179       using PointerType      = ElementType*;                     //!< Pointer return type.
180       using ReferenceType    = ElementType&;                     //!< Reference return type.
181       using DifferenceType   = ptrdiff_t;                        //!< Difference between two iterators.
182 
183       // STL iterator requirements
184       using iterator_category = IteratorCategory;  //!< The iterator category.
185       using value_type        = ValueType;         //!< Type of the underlying elements.
186       using pointer           = PointerType;       //!< Pointer return type.
187       using reference         = ReferenceType;     //!< Reference return type.
188       using difference_type   = DifferenceType;    //!< Difference between two iterators.
189 
190       //! ConstIterator type of the left-hand side dense vector expression.
191       using IteratorType = ConstIterator_t<VT>;
192       //*******************************************************************************************
193 
194       //**Constructor******************************************************************************
195       /*!\brief Constructor for the ConstIterator class.
196       //
197       // \param it Iterator to the initial vector element.
198       // \param op The custom unary operation.
199       */
ConstIterator(IteratorType it,OP op)200       inline BLAZE_DEVICE_CALLABLE ConstIterator( IteratorType it, OP op )
201          : it_( it )             // Iterator to the current vector element
202          , op_( std::move(op) )  // The custom unary operation
203       {}
204       //*******************************************************************************************
205 
206       //**Addition assignment operator*************************************************************
207       /*!\brief Addition assignment operator.
208       //
209       // \param inc The increment of the iterator.
210       // \return The incremented iterator.
211       */
212       inline BLAZE_DEVICE_CALLABLE ConstIterator& operator+=( size_t inc ) {
213          it_ += inc;
214          return *this;
215       }
216       //*******************************************************************************************
217 
218       //**Subtraction assignment operator**********************************************************
219       /*!\brief Subtraction assignment operator.
220       //
221       // \param dec The decrement of the iterator.
222       // \return The decremented iterator.
223       */
224       inline BLAZE_DEVICE_CALLABLE ConstIterator& operator-=( size_t dec ) {
225          it_ -= dec;
226          return *this;
227       }
228       //*******************************************************************************************
229 
230       //**Prefix increment operator****************************************************************
231       /*!\brief Pre-increment operator.
232       //
233       // \return Reference to the incremented iterator.
234       */
235       inline BLAZE_DEVICE_CALLABLE ConstIterator& operator++() {
236          ++it_;
237          return *this;
238       }
239       //*******************************************************************************************
240 
241       //**Postfix increment operator***************************************************************
242       /*!\brief Post-increment operator.
243       //
244       // \return The previous position of the iterator.
245       */
246       inline BLAZE_DEVICE_CALLABLE const ConstIterator operator++( int ) {
247          return ConstIterator( it_++, op_ );
248       }
249       //*******************************************************************************************
250 
251       //**Prefix decrement operator****************************************************************
252       /*!\brief Pre-decrement operator.
253       //
254       // \return Reference to the decremented iterator.
255       */
256       inline BLAZE_DEVICE_CALLABLE ConstIterator& operator--() {
257          --it_;
258          return *this;
259       }
260       //*******************************************************************************************
261 
262       //**Postfix decrement operator***************************************************************
263       /*!\brief Post-decrement operator.
264       //
265       // \return The previous position of the iterator.
266       */
267       inline BLAZE_DEVICE_CALLABLE const ConstIterator operator--( int ) {
268          return ConstIterator( it_--, op_ );
269       }
270       //*******************************************************************************************
271 
272       //**Element access operator******************************************************************
273       /*!\brief Direct access to the element at the current iterator position.
274       //
275       // \return The resulting value.
276       */
277       inline BLAZE_DEVICE_CALLABLE ReturnType operator*() const {
278          return op_( *it_ );
279       }
280       //*******************************************************************************************
281 
282       //**Load function****************************************************************************
283       /*!\brief Access to the SIMD elements of the vector.
284       //
285       // \return The resulting SIMD element.
286       */
load()287       inline auto load() const noexcept {
288          return op_.load( it_.load() );
289       }
290       //*******************************************************************************************
291 
292       //**Equality operator************************************************************************
293       /*!\brief Equality comparison between two ConstIterator objects.
294       //
295       // \param rhs The right-hand side iterator.
296       // \return \a true if the iterators refer to the same element, \a false if not.
297       */
298       inline BLAZE_DEVICE_CALLABLE bool operator==( const ConstIterator& rhs ) const {
299          return it_ == rhs.it_;
300       }
301       //*******************************************************************************************
302 
303       //**Inequality operator**********************************************************************
304       /*!\brief Inequality comparison between two ConstIterator objects.
305       //
306       // \param rhs The right-hand side iterator.
307       // \return \a true if the iterators don't refer to the same element, \a false if they do.
308       */
309       inline BLAZE_DEVICE_CALLABLE bool operator!=( const ConstIterator& rhs ) const {
310          return it_ != rhs.it_;
311       }
312       //*******************************************************************************************
313 
314       //**Less-than operator***********************************************************************
315       /*!\brief Less-than comparison between two ConstIterator objects.
316       //
317       // \param rhs The right-hand side iterator.
318       // \return \a true if the left-hand side iterator is smaller, \a false if not.
319       */
320       inline BLAZE_DEVICE_CALLABLE bool operator<( const ConstIterator& rhs ) const {
321          return it_ < rhs.it_;
322       }
323       //*******************************************************************************************
324 
325       //**Greater-than operator********************************************************************
326       /*!\brief Greater-than comparison between two ConstIterator objects.
327       //
328       // \param rhs The right-hand side iterator.
329       // \return \a true if the left-hand side iterator is greater, \a false if not.
330       */
331       inline BLAZE_DEVICE_CALLABLE bool operator>( const ConstIterator& rhs ) const {
332          return it_ > rhs.it_;
333       }
334       //*******************************************************************************************
335 
336       //**Less-or-equal-than operator**************************************************************
337       /*!\brief Less-than comparison between two ConstIterator objects.
338       //
339       // \param rhs The right-hand side iterator.
340       // \return \a true if the left-hand side iterator is smaller or equal, \a false if not.
341       */
342       inline BLAZE_DEVICE_CALLABLE bool operator<=( const ConstIterator& rhs ) const {
343          return it_ <= rhs.it_;
344       }
345       //*******************************************************************************************
346 
347       //**Greater-or-equal-than operator***********************************************************
348       /*!\brief Greater-than comparison between two ConstIterator objects.
349       //
350       // \param rhs The right-hand side iterator.
351       // \return \a true if the left-hand side iterator is greater or equal, \a false if not.
352       */
353       inline BLAZE_DEVICE_CALLABLE bool operator>=( const ConstIterator& rhs ) const {
354          return it_ >= rhs.it_;
355       }
356       //*******************************************************************************************
357 
358       //**Subtraction operator*********************************************************************
359       /*!\brief Calculating the number of elements between two iterators.
360       //
361       // \param rhs The right-hand side iterator.
362       // \return The number of elements between the two iterators.
363       */
364       inline BLAZE_DEVICE_CALLABLE DifferenceType operator-( const ConstIterator& rhs ) const {
365          return it_ - rhs.it_;
366       }
367       //*******************************************************************************************
368 
369       //**Addition operator************************************************************************
370       /*!\brief Addition between a ConstIterator and an integral value.
371       //
372       // \param it The iterator to be incremented.
373       // \param inc The number of elements the iterator is incremented.
374       // \return The incremented iterator.
375       */
376       friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
377          return ConstIterator( it.it_ + inc, it.op_ );
378       }
379       //*******************************************************************************************
380 
381       //**Addition operator************************************************************************
382       /*!\brief Addition between an integral value and a ConstIterator.
383       //
384       // \param inc The number of elements the iterator is incremented.
385       // \param it The iterator to be incremented.
386       // \return The incremented iterator.
387       */
388       friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
389          return ConstIterator( it.it_ + inc, it.op_ );
390       }
391       //*******************************************************************************************
392 
393       //**Subtraction operator*********************************************************************
394       /*!\brief Subtraction between a ConstIterator and an integral value.
395       //
396       // \param it The iterator to be decremented.
397       // \param dec The number of elements the iterator is decremented.
398       // \return The decremented iterator.
399       */
400       friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
401          return ConstIterator( it.it_ - dec, it.op_ );
402       }
403       //*******************************************************************************************
404 
405     private:
406       //**Member variables*************************************************************************
407       IteratorType it_;  //!< Iterator to the current vector element.
408       OP           op_;  //!< The custom unary operation.
409       //*******************************************************************************************
410    };
411    //**********************************************************************************************
412 
413  public:
414    //**Compilation flags***************************************************************************
415    //! Compilation switch for the expression template evaluation strategy.
416    static constexpr bool simdEnabled =
417       ( VT::simdEnabled &&
418         If_t< HasSIMDEnabled_v<OP>, GetSIMDEnabled<OP,ET>, HasLoad<OP> >::value );
419 
420    //! Compilation switch for the expression template assignment strategy.
421    static constexpr bool smpAssignable = VT::smpAssignable;
422    //**********************************************************************************************
423 
424    //**SIMD properties*****************************************************************************
425    //! The number of elements packed within a single SIMD element.
426    static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
427    //**********************************************************************************************
428 
429    //**Constructor*********************************************************************************
430    /*!\brief Constructor for the DVecMapExpr class.
431    //
432    // \param dv The dense vector operand of the map expression.
433    // \param op The custom unary operation.
434    */
DVecMapExpr(const VT & dv,OP op)435    inline DVecMapExpr( const VT& dv, OP op ) noexcept
436       : dv_( dv )             // Dense vector of the map expression
437       , op_( std::move(op) )  // The custom unary operation
438    {}
439    //**********************************************************************************************
440 
441    //**Subscript operator**************************************************************************
442    /*!\brief Subscript operator for the direct access to the vector elements.
443    //
444    // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
445    // \return The resulting value.
446    */
447    inline ReturnType operator[]( size_t index ) const {
448       BLAZE_INTERNAL_ASSERT( index < dv_.size(), "Invalid vector access index" );
449       return op_( dv_[index] );
450    }
451    //**********************************************************************************************
452 
453    //**At function*********************************************************************************
454    /*!\brief Checked access to the vector elements.
455    //
456    // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
457    // \return The resulting value.
458    // \exception std::out_of_range Invalid vector access index.
459    */
at(size_t index)460    inline ReturnType at( size_t index ) const {
461       if( index >= dv_.size() ) {
462          BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
463       }
464       return (*this)[index];
465    }
466    //**********************************************************************************************
467 
468    //**Load function*******************************************************************************
469    /*!\brief Access to the SIMD elements of the vector.
470    //
471    // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
472    // \return Reference to the accessed values.
473    */
load(size_t index)474    BLAZE_ALWAYS_INLINE auto load( size_t index ) const noexcept {
475       BLAZE_INTERNAL_ASSERT( index < dv_.size()     , "Invalid vector access index" );
476       BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL, "Invalid vector access index" );
477       return op_.load( dv_.load( index ) );
478    }
479    //**********************************************************************************************
480 
481    //**Begin function******************************************************************************
482    /*!\brief Returns an iterator to the first non-zero element of the dense vector.
483    //
484    // \return Iterator to the first non-zero element of the dense vector.
485    */
begin()486    inline ConstIterator begin() const {
487       return ConstIterator( dv_.begin(), op_ );
488    }
489    //**********************************************************************************************
490 
491    //**End function********************************************************************************
492    /*!\brief Returns an iterator just past the last non-zero element of the dense vector.
493    //
494    // \return Iterator just past the last non-zero element of the dense vector.
495    */
end()496    inline ConstIterator end() const {
497       return ConstIterator( dv_.end(), op_ );
498    }
499    //**********************************************************************************************
500 
501    //**Size function*******************************************************************************
502    /*!\brief Returns the current size/dimension of the vector.
503    //
504    // \return The size of the vector.
505    */
size()506    inline size_t size() const noexcept {
507       return dv_.size();
508    }
509    //**********************************************************************************************
510 
511    //**Operand access******************************************************************************
512    /*!\brief Returns the dense vector operand.
513    //
514    // \return The dense vector operand.
515    */
operand()516    inline Operand operand() const noexcept {
517       return dv_;
518    }
519    //**********************************************************************************************
520 
521    //**Operation access****************************************************************************
522    /*!\brief Returns a copy of the custom operation.
523    //
524    // \return A copy of the custom operation.
525    */
operation()526    inline Operation operation() const {
527       return op_;
528    }
529    //**********************************************************************************************
530 
531    //**********************************************************************************************
532    /*!\brief Returns whether the expression can alias with the given address \a alias.
533    //
534    // \param alias The alias to be checked.
535    // \return \a true in case the expression can alias, \a false otherwise.
536    */
537    template< typename T >
canAlias(const T * alias)538    inline bool canAlias( const T* alias ) const noexcept {
539       return IsExpression_v<VT> && dv_.canAlias( alias );
540    }
541    //**********************************************************************************************
542 
543    //**********************************************************************************************
544    /*!\brief Returns whether the expression is aliased with the given address \a alias.
545    //
546    // \param alias The alias to be checked.
547    // \return \a true in case an alias effect is detected, \a false otherwise.
548    */
549    template< typename T >
isAliased(const T * alias)550    inline bool isAliased( const T* alias ) const noexcept {
551       return dv_.isAliased( alias );
552    }
553    //**********************************************************************************************
554 
555    //**********************************************************************************************
556    /*!\brief Returns whether the operands of the expression are properly aligned in memory.
557    //
558    // \return \a true in case the operands are aligned, \a false if not.
559    */
isAligned()560    inline bool isAligned() const noexcept {
561       return dv_.isAligned();
562    }
563    //**********************************************************************************************
564 
565    //**********************************************************************************************
566    /*!\brief Returns whether the expression can be used in SMP assignments.
567    //
568    // \return \a true in case the expression can be used in SMP assignments, \a false if not.
569    */
canSMPAssign()570    inline bool canSMPAssign() const noexcept {
571       return dv_.canSMPAssign();
572    }
573    //**********************************************************************************************
574 
575  private:
576    //**Member variables****************************************************************************
577    Operand   dv_;  //!< Dense vector of the map expression.
578    Operation op_;  //!< The custom unary operation.
579    //**********************************************************************************************
580 
581    //**Assignment to dense vectors*****************************************************************
582    /*! \cond BLAZE_INTERNAL */
583    /*!\brief Assignment of a dense vector map expression to a dense vector.
584    // \ingroup dense_vector
585    //
586    // \param lhs The target left-hand side dense vector.
587    // \param rhs The right-hand side map expression to be assigned.
588    // \return void
589    //
590    // This function implements the performance optimized assignment of a dense vector map
591    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
592    // this function can only be selected by the compiler in case the operand requires an
593    // intermediate evaluation and the underlying numeric data type of the operand and the
594    // target vector are identical.
595    */
596    template< typename VT2 >  // Type of the target dense vector
597    friend inline auto assign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
598       -> EnableIf_t< UseAssign_v<VT2> &&
599                      IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
600    {
601       BLAZE_FUNCTION_TRACE;
602 
603       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
604 
605       assign( *lhs, rhs.dv_ );
606       assign( *lhs, map( *lhs, rhs.op_ ) );
607    }
608    /*! \endcond */
609    //**********************************************************************************************
610 
611    //**Assignment to dense vectors*****************************************************************
612    /*! \cond BLAZE_INTERNAL */
613    /*!\brief Assignment of a dense vector map expression to a dense vector.
614    // \ingroup dense_vector
615    //
616    // \param lhs The target left-hand side dense vector.
617    // \param rhs The right-hand side map expression to be assigned.
618    // \return void
619    //
620    // This function implements the performance optimized assignment of a dense vector map
621    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
622    // this function can only be selected by the compiler in case the operand requires an
623    // intermediate evaluation and the underlying numeric data type of the operand and the
624    // target vector differ.
625    */
626    template< typename VT2 >  // Type of the target dense vector
627    friend inline auto assign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
628       -> EnableIf_t< UseAssign_v<VT2> &&
629                      !IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
630    {
631       BLAZE_FUNCTION_TRACE;
632 
633       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
634       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
635       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
636 
637       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
638 
639       const RT tmp( serial( rhs.dv_ ) );
640       assign( *lhs, map( tmp, rhs.op_ ) );
641    }
642    /*! \endcond */
643    //**********************************************************************************************
644 
645    //**Assignment to sparse vectors****************************************************************
646    /*! \cond BLAZE_INTERNAL */
647    /*!\brief Assignment of a dense vector map expression to a sparse vector.
648    // \ingroup dense_vector
649    //
650    // \param lhs The target left-hand side sparse vector.
651    // \param rhs The right-hand side map expression to be assigned.
652    // \return void
653    //
654    // This function implements the performance optimized assignment of a dense vector map
655    // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
656    // this function can only be selected by the compiler in case the operand requires an
657    // intermediate evaluation.
658    */
659    template< typename VT2 >  // Type of the target sparse vector
660    friend inline auto assign( SparseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
661       -> EnableIf_t< UseAssign_v<VT2> >
662    {
663       BLAZE_FUNCTION_TRACE;
664 
665       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
666       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
667       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
668 
669       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
670 
671       const RT tmp( serial( rhs.dv_ ) );
672       assign( *lhs, map( tmp, rhs.op_ ) );
673    }
674    /*! \endcond */
675    //**********************************************************************************************
676 
677    //**Addition assignment to dense vectors********************************************************
678    /*! \cond BLAZE_INTERNAL */
679    /*!\brief Addition assignment of a dense vector map expression to a dense vector.
680    // \ingroup dense_vector
681    //
682    // \param lhs The target left-hand side dense vector.
683    // \param rhs The right-hand side map expression to be added.
684    // \return void
685    //
686    // This function implements the performance optimized addition assignment of a dense vector
687    // map expression to a dense vector. Due to the explicit application of the SFINAE principle,
688    // this function can only be selected by the compiler in case the operand requires an
689    // intermediate evaluation.
690    */
691    template< typename VT2 >  // Type of the target dense vector
692    friend inline auto addAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
693       -> EnableIf_t< UseAssign_v<VT2> >
694    {
695       BLAZE_FUNCTION_TRACE;
696 
697       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
698       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
699       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
700 
701       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
702 
703       const RT tmp( serial( rhs.dv_ ) );
704       addAssign( *lhs, map( tmp, rhs.op_ ) );
705    }
706    /*! \endcond */
707    //**********************************************************************************************
708 
709    //**Addition assignment to sparse vectors*******************************************************
710    // No special implementation for the addition assignment to sparse vectors.
711    //**********************************************************************************************
712 
713    //**Subtraction assignment to dense vectors*****************************************************
714    /*! \cond BLAZE_INTERNAL */
715    /*!\brief Subtraction assignment of a dense vector map expression to a dense vector.
716    // \ingroup dense_vector
717    //
718    // \param lhs The target left-hand side dense vector.
719    // \param rhs The right-hand side map expression to be subtracted.
720    // \return void
721    //
722    // This function implements the performance optimized subtraction assignment of a dense
723    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
724    // principle, this function can only be selected by the compiler in case the operand
725    // requires an intermediate evaluation.
726    */
727    template< typename VT2 >  // Type of the target dense vector
728    friend inline auto subAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
729       -> EnableIf_t< UseAssign_v<VT2> >
730    {
731       BLAZE_FUNCTION_TRACE;
732 
733       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
734       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
735       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
736 
737       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
738 
739       const RT tmp( serial( rhs.dv_ ) );
740       subAssign( *lhs, map( tmp, rhs.op_ ) );
741    }
742    /*! \endcond */
743    //**********************************************************************************************
744 
745    //**Subtraction assignment to sparse vectors****************************************************
746    // No special implementation for the subtraction assignment to sparse vectors.
747    //**********************************************************************************************
748 
749    //**Multiplication assignment to dense vectors**************************************************
750    /*! \cond BLAZE_INTERNAL */
751    /*!\brief Multiplication assignment of a dense vector map expression to a dense vector.
752    // \ingroup dense_vector
753    //
754    // \param lhs The target left-hand side dense vector.
755    // \param rhs The right-hand side map expression to be multiplied.
756    // \return void
757    //
758    // This function implements the performance optimized multiplication assignment of a dense
759    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
760    // principle, this function can only be selected by the compiler in case the operand requires
761    // an intermediate evaluation.
762    */
763    template< typename VT2 >  // Type of the target dense vector
764    friend inline auto multAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
765       -> EnableIf_t< UseAssign_v<VT2> >
766    {
767       BLAZE_FUNCTION_TRACE;
768 
769       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
770       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
771       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
772 
773       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
774 
775       const RT tmp( serial( rhs.dv_ ) );
776       multAssign( *lhs, map( tmp, rhs.op_ ) );
777    }
778    /*! \endcond */
779    //**********************************************************************************************
780 
781    //**Multiplication assignment to sparse vectors*************************************************
782    // No special implementation for the multiplication assignment to sparse vectors.
783    //**********************************************************************************************
784 
785    //**Division assignment to dense vectors********************************************************
786    /*! \cond BLAZE_INTERNAL */
787    /*!\brief Division assignment of a dense vector map expression to a dense vector.
788    // \ingroup dense_vector
789    //
790    // \param lhs The target left-hand side dense vector.
791    // \param rhs The right-hand side map expression divisor.
792    // \return void
793    //
794    // This function implements the performance optimized division assignment of a dense vector
795    // map expression to a dense vector. Due to the explicit application of the SFINAE principle,
796    // this function can only be selected by the compiler in case the operand requires an
797    // intermediate evaluation.
798    */
799    template< typename VT2 >  // Type of the target dense vector
800    friend inline auto divAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
801       -> EnableIf_t< UseAssign_v<VT2> >
802    {
803       BLAZE_FUNCTION_TRACE;
804 
805       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
806       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
807       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
808 
809       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
810 
811       const RT tmp( serial( rhs.dv_ ) );
812       divAssign( *lhs, map( tmp, rhs.op_ ) );
813    }
814    /*! \endcond */
815    //**********************************************************************************************
816 
817    //**Division assignment to sparse vectors*******************************************************
818    // No special implementation for the division assignment to sparse vectors.
819    //**********************************************************************************************
820 
821    //**SMP assignment to dense vectors*************************************************************
822    /*! \cond BLAZE_INTERNAL */
823    /*!\brief SMP assignment of a dense vector map expression to a dense vector.
824    // \ingroup dense_vector
825    //
826    // \param lhs The target left-hand side dense vector.
827    // \param rhs The right-hand side map expression to be assigned.
828    // \return void
829    //
830    // This function implements the performance optimized SMP assignment of a dense vector map
831    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
832    // this function can only be selected by the compiler in case the expression specific parallel
833    // evaluation strategy is selected and the underlying numeric data type of the operand and the
834    // target vector are identical
835    */
836    template< typename VT2 >  // Type of the target dense vector
837    friend inline auto smpAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
838       -> EnableIf_t< UseSMPAssign_v<VT2> &&
839                      IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
840    {
841       BLAZE_FUNCTION_TRACE;
842 
843       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
844 
845       smpAssign( *lhs, rhs.dv_ );
846       smpAssign( *lhs, map( *lhs, rhs.op_ ) );
847    }
848    /*! \endcond */
849    //**********************************************************************************************
850 
851    //**SMP assignment to dense vectors*************************************************************
852    /*! \cond BLAZE_INTERNAL */
853    /*!\brief SMP assignment of a dense vector map expression to a dense vector.
854    // \ingroup dense_vector
855    //
856    // \param lhs The target left-hand side dense vector.
857    // \param rhs The right-hand side map expression to be assigned.
858    // \return void
859    //
860    // This function implements the performance optimized SMP assignment of a dense vector map
861    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
862    // this function can only be selected by the compiler in case the expression specific parallel
863    // evaluation strategy is selected and the underlying numeric data type of the operand and the
864    // target vector differ.
865    */
866    template< typename VT2 >  // Type of the target dense vector
867    friend inline auto smpAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
868       -> EnableIf_t< UseSMPAssign_v<VT2> &&
869                      !IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
870    {
871       BLAZE_FUNCTION_TRACE;
872 
873       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
874       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
875       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
876 
877       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
878 
879       const RT tmp( rhs.dv_ );
880       smpAssign( *lhs, map( tmp, rhs.op_ ) );
881    }
882    /*! \endcond */
883    //**********************************************************************************************
884 
885    //**SMP assignment to sparse vectors************************************************************
886    /*! \cond BLAZE_INTERNAL */
887    /*!\brief SMP assignment of a dense vector map expression to a sparse vector.
888    // \ingroup dense_vector
889    //
890    // \param lhs The target left-hand side sparse vector.
891    // \param rhs The right-hand side map expression to be assigned.
892    // \return void
893    //
894    // This function implements the performance optimized SMP assignment of a dense vector map
895    // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
896    // this function can only be selected by the compiler in case the expression specific parallel
897    // evaluation strategy is selected.
898    */
899    template< typename VT2 >  // Type of the target sparse vector
900    friend inline auto smpAssign( SparseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
901       -> EnableIf_t< UseSMPAssign_v<VT2> >
902    {
903       BLAZE_FUNCTION_TRACE;
904 
905       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
906       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
907       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
908 
909       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
910 
911       const RT tmp( rhs.dv_ );
912       smpAssign( *lhs, map( tmp, rhs.op_ ) );
913    }
914    /*! \endcond */
915    //**********************************************************************************************
916 
917    //**SMP addition assignment to dense vectors****************************************************
918    /*! \cond BLAZE_INTERNAL */
919    /*!\brief SMP addition assignment of a dense vector map expression to a dense vector.
920    // \ingroup dense_vector
921    //
922    // \param lhs The target left-hand side dense vector.
923    // \param rhs The right-hand side map expression to be added.
924    // \return void
925    //
926    // This function implements the performance optimized SMP addition assignment of a dense
927    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
928    // principle, this function can only be selected by the compiler in case the expression
929    // specific parallel evaluation strategy is selected.
930    */
931    template< typename VT2 >  // Type of the target dense vector
932    friend inline auto smpAddAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
933       -> EnableIf_t< UseSMPAssign_v<VT2> >
934    {
935       BLAZE_FUNCTION_TRACE;
936 
937       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
938       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
939       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
940 
941       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
942 
943       const RT tmp( rhs.dv_ );
944       smpAddAssign( *lhs, map( tmp, rhs.op_ ) );
945    }
946    /*! \endcond */
947    //**********************************************************************************************
948 
949    //**SMP addition assignment to sparse vectors***************************************************
950    // No special implementation for the SMP addition assignment to sparse vectors.
951    //**********************************************************************************************
952 
953    //**SMP subtraction assignment to dense vectors*************************************************
954    /*! \cond BLAZE_INTERNAL */
955    /*!\brief SMP subtraction assignment of a dense vector map expression to a dense vector.
956    // \ingroup dense_vector
957    //
958    // \param lhs The target left-hand side dense vector.
959    // \param rhs The right-hand side map expression to be subtracted.
960    // \return void
961    //
962    // This function implements the performance optimized SMP subtraction assignment of a dense
963    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
964    // principle, this function can only be selected by the compiler in case the expression
965    // specific parallel evaluation strategy is selected.
966    */
967    template< typename VT2 >  // Type of the target dense vector
968    friend inline auto smpSubAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
969       -> EnableIf_t< UseSMPAssign_v<VT2> >
970    {
971       BLAZE_FUNCTION_TRACE;
972 
973       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
974       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
975       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
976 
977       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
978 
979       const RT tmp( rhs.dv_ );
980       smpSubAssign( *lhs, map( tmp, rhs.op_ ) );
981    }
982    /*! \endcond */
983    //**********************************************************************************************
984 
985    //**SMP subtraction assignment to sparse vectors************************************************
986    // No special implementation for the SMP subtraction assignment to sparse vectors.
987    //**********************************************************************************************
988 
989    //**SMP multiplication assignment to dense vectors**********************************************
990    /*! \cond BLAZE_INTERNAL */
991    /*!\brief SMP multiplication assignment of a dense vector map expression to a dense vector.
992    // \ingroup dense_vector
993    //
994    // \param lhs The target left-hand side dense vector.
995    // \param rhs The right-hand side map expression to be multiplied.
996    // \return void
997    //
998    // This function implements the performance optimized SMP multiplication assignment of a
999    // dense vector map expression to a dense vector. Due to the explicit application of the
1000    // SFINAE principle, this function can only be selected by the compiler in case the
1001    // expression specific parallel evaluation strategy is selected.
1002    */
1003    template< typename VT2 >  // Type of the target dense vector
1004    friend inline auto smpMultAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
1005       -> EnableIf_t< UseSMPAssign_v<VT2> >
1006    {
1007       BLAZE_FUNCTION_TRACE;
1008 
1009       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
1010       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
1011       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
1012 
1013       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
1014 
1015       const RT tmp( rhs.dv_ );
1016       smpMultAssign( *lhs, map( tmp, rhs.op_ ) );
1017    }
1018    /*! \endcond */
1019    //**********************************************************************************************
1020 
1021    //**SMP multiplication assignment to sparse vectors*********************************************
1022    // No special implementation for the SMP multiplication assignment to sparse vectors.
1023    //**********************************************************************************************
1024 
1025    //**SMP division assignment to dense vectors****************************************************
1026    /*! \cond BLAZE_INTERNAL */
1027    /*!\brief SMP division assignment of a dense vector map expression to a dense vector.
1028    // \ingroup dense_vector
1029    //
1030    // \param lhs The target left-hand side dense vector.
1031    // \param rhs The right-hand side map expression divisor.
1032    // \return void
1033    //
1034    // This function implements the performance optimized SMP division assignment of a dense
1035    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
1036    // principle, this function can only be selected by the compiler in case the expression
1037    // specific parallel evaluation strategy is selected.
1038    */
1039    template< typename VT2 >  // Type of the target dense vector
1040    friend inline auto smpDivAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
1041       -> EnableIf_t< UseSMPAssign_v<VT2> >
1042    {
1043       BLAZE_FUNCTION_TRACE;
1044 
1045       BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
1046       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
1047       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
1048 
1049       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
1050 
1051       const RT tmp( rhs.dv_ );
1052       smpDivAssign( *lhs, map( tmp, rhs.op_ ) );
1053    }
1054    /*! \endcond */
1055    //**********************************************************************************************
1056 
1057    //**SMP division assignment to sparse vectors***************************************************
1058    // No special implementation for the SMP division assignment to sparse vectors.
1059    //**********************************************************************************************
1060 
1061    //**Compile time checks*************************************************************************
1062    /*! \cond BLAZE_INTERNAL */
1063    BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( VT );
1064    BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( VT, TF );
1065    /*! \endcond */
1066    //**********************************************************************************************
1067 };
1068 //*************************************************************************************************
1069 
1070 
1071 
1072 
1073 //=================================================================================================
1074 //
1075 //  GLOBAL FUNCTIONS
1076 //
1077 //=================================================================================================
1078 
1079 //*************************************************************************************************
1080 /*!\brief Evaluates the given custom operation on each single element of the dense vector \a dv.
1081 // \ingroup dense_vector
1082 //
1083 // \param dv The input vector.
1084 // \param op The custom operation.
1085 // \return The custom operation applied to each single element of \a dv.
1086 //
1087 // The \a map() function evaluates the given custom operation on each element of the input
1088 // vector \a dv. The function returns an expression representing this operation.\n
1089 // The following example demonstrates the use of the \a map() function:
1090 
1091    \code
1092    blaze::DynamicVector<double> a, b;
1093    // ... Resizing and initialization
1094    b = map( a, []( double a ){ return std::sqrt( a ); } );
1095    \endcode
1096 */
1097 template< typename VT    // Type of the dense vector
1098         , bool TF        // Transpose flag
1099         , typename OP >  // Type of the custom operation
decltype(auto)1100 inline decltype(auto) map( const DenseVector<VT,TF>& dv, OP op )
1101 {
1102    BLAZE_FUNCTION_TRACE;
1103 
1104    using ReturnType = const DVecMapExpr<VT,OP,TF>;
1105    return ReturnType( *dv, std::move(op) );
1106 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1111 /*!\brief Evaluates the given custom operation on each single element of the dense vector \a dv.
1112 // \ingroup dense_vector
1113 //
1114 // \param dv The input vector.
1115 // \param op The custom operation.
1116 // \return The custom operation applied to each single element of \a dv.
1117 //
1118 // The \a forEach() function evaluates the given custom operation on each element of the input
1119 // vector \a dv. The function returns an expression representing this operation.\n
1120 // The following example demonstrates the use of the \a forEach() function:
1121 
1122    \code
1123    blaze::DynamicVector<double> a, b;
1124    // ... Resizing and initialization
1125    b = forEach( a, []( double a ){ return std::sqrt( a ); } );
1126    \endcode
1127 */
1128 template< typename VT    // Type of the dense vector
1129         , bool TF        // Transpose flag
1130         , typename OP >  // Type of the custom operation
decltype(auto)1131 inline decltype(auto) forEach( const DenseVector<VT,TF>& dv, OP op )
1132 {
1133    BLAZE_FUNCTION_TRACE;
1134 
1135    return map( *dv, std::move(op) );
1136 }
1137 //*************************************************************************************************
1138 
1139 
1140 //*************************************************************************************************
1141 /*!\brief Computes the componentwise minimum of a dense vector \a dv and a scalar.
1142 // \ingroup dense_vector
1143 //
1144 // \param dv The left-hand side dense vector operand.
1145 // \param scalar The right-hand side scalar value.
1146 // \return The resulting dense vector.
1147 //
1148 // This operator computes the componentwise minimum of a dense vector \a dv and a uniform vector
1149 // represented by the scalar value \a scalar. The function returns an expression representing this
1150 // operation.\n
1151 // The following example demonstrates the use of the \a min() function:
1152 
1153    \code
1154    blaze::DynamicVector<double> a, b;
1155    // ... Resizing and initialization
1156    b = min( a, 0.0 );
1157    \endcode
1158 */
1159 template< typename VT  // Type of the dense vector
1160         , bool TF      // Transpose flag
1161         , typename ST  // Type of the scalar exponent
1162         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1163 decltype(auto) min( const DenseVector<VT,TF>& dv, ST scalar )
1164 {
1165    BLAZE_FUNCTION_TRACE;
1166 
1167    using ET = ElementType_t<VT>;
1168    using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MapTrait_t<ET,ST,Min>, ST >;
1169    return map( *dv, bind2nd( Min(), ScalarType( scalar ) ) );
1170 }
1171 //*************************************************************************************************
1172 
1173 
1174 //*************************************************************************************************
1175 /*!\brief Computes the componentwise minimum of a scalar and a dense vector \a dv.
1176 // \ingroup dense_vector
1177 //
1178 // \param scalar The left-hand side scalar value.
1179 // \param dv The right-hand side dense vector operand.
1180 // \return The resulting dense vector.
1181 //
1182 // This operator computes the componentwise minimum of a uniform vector represented by the scalar
1183 // value \a scalar and a dense vector \a dv. The function returns an expression representing this
1184 // operation.\n
1185 // The following example demonstrates the use of the \a min() function:
1186 
1187    \code
1188    blaze::DynamicVector<double> a, b;
1189    // ... Resizing and initialization
1190    b = min( 0.0, a );
1191    \endcode
1192 */
1193 template< typename ST  // Type of the scalar exponent
1194         , typename VT  // Type of the dense vector
1195         , bool TF      // Transpose flag
1196         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1197 decltype(auto) min( ST scalar, const DenseVector<VT,TF>& dv )
1198 {
1199    BLAZE_FUNCTION_TRACE;
1200 
1201    using ET = ElementType_t<VT>;
1202    using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, MapTrait_t<ST,ET,Min>, ST >;
1203    return map( *dv, bind1st( Min(), ScalarType( scalar ) ) );
1204 }
1205 //*************************************************************************************************
1206 
1207 
1208 //*************************************************************************************************
1209 /*!\brief Computes the componentwise maximum of a dense vector \a dv and a scalar.
1210 // \ingroup dense_vector
1211 //
1212 // \param dv The left-hand side dense vector operand.
1213 // \param scalar The right-hand side scalar value.
1214 // \return The resulting dense vector.
1215 //
1216 // This operator computes the componentwise maximum of a dense vector \a dv and a uniform vector
1217 // represented by the scalar value \a scalar. The function returns an expression representing this
1218 // operation.\n
1219 // The following example demonstrates the use of the \a max() function:
1220 
1221    \code
1222    blaze::DynamicVector<double> a, b;
1223    // ... Resizing and initialization
1224    b = max( a, 0.0 );
1225    \endcode
1226 
1227 // In case the current sizes of the two given vectors don't match, a \a std::invalid_argument
1228 // is thrown.
1229 */
1230 template< typename VT  // Type of the dense vector
1231         , bool TF      // Transpose flag
1232         , typename ST  // Type of the scalar exponent
1233         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1234 decltype(auto) max( const DenseVector<VT,TF>& dv, ST scalar )
1235 {
1236    BLAZE_FUNCTION_TRACE;
1237 
1238    using ET = ElementType_t<VT>;
1239    using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MapTrait_t<ET,ST,Max>, ST >;
1240    return map( *dv, bind2nd( Max(), ScalarType( scalar ) ) );
1241 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1246 /*!\brief Computes the componentwise maximum of a scalar and a dense vector \a dv.
1247 // \ingroup dense_vector
1248 //
1249 // \param scalar The left-hand side scalar value.
1250 // \param dv The right-hand side dense vector operand.
1251 // \return The resulting dense vector.
1252 //
1253 // This operator computes the componentwise maximum of a uniform vector represented by the scalar
1254 // value \a scalar and a dense vector \a dv. The function returns an expression representing this
1255 // operation.\n
1256 // The following example demonstrates the use of the \a max() function:
1257 
1258    \code
1259    blaze::DynamicVector<double> a, b;
1260    // ... Resizing and initialization
1261    b = max( 0.0, a );
1262    \endcode
1263 */
1264 template< typename ST  // Type of the scalar exponent
1265         , typename VT  // Type of the dense vector
1266         , bool TF      // Transpose flag
1267         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1268 decltype(auto) max( ST scalar, const DenseVector<VT,TF>& dv )
1269 {
1270    BLAZE_FUNCTION_TRACE;
1271 
1272    using ET = ElementType_t<VT>;
1273    using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, MapTrait_t<ST,ET,Max>, ST >;
1274    return map( *dv, bind1st( Max(), ScalarType( scalar ) ) );
1275 }
1276 //*************************************************************************************************
1277 
1278 
1279 //*************************************************************************************************
1280 /*!\brief Applies the \a abs() function to each single element of the dense vector \a dv.
1281 // \ingroup dense_vector
1282 //
1283 // \param dv The input vector.
1284 // \return The resulting dense vector.
1285 //
1286 // This function applies the \a abs() function to each element of the input vector \a dv. The
1287 // function returns an expression representing this operation.\n
1288 // The following example demonstrates the use of the \a abs() function:
1289 
1290    \code
1291    blaze::DynamicVector<double> a, b;
1292    // ... Resizing and initialization
1293    b = abs( a );
1294    \endcode
1295 */
1296 template< typename VT  // Type of the dense vector
1297         , bool TF >    // Transpose flag
decltype(auto)1298 inline decltype(auto) abs( const DenseVector<VT,TF>& dv )
1299 {
1300    BLAZE_FUNCTION_TRACE;
1301 
1302    return map( *dv, Abs() );
1303 }
1304 //*************************************************************************************************
1305 
1306 
1307 //*************************************************************************************************
1308 /*!\brief Applies the \a sign() function to each single element of the dense vector \a dv.
1309 // \ingroup dense_vector
1310 //
1311 // \param dv The input vector.
1312 // \return The resulting dense vector.
1313 //
1314 // This function applies the \a sign() function to each element of the input vector \a dv. The
1315 // function returns an expression representing this operation.\n
1316 // The following example demonstrates the use of the \a sign() function:
1317 
1318    \code
1319    blaze::DynamicVector<double> a, b;
1320    // ... Resizing and initialization
1321    b = sign( a );
1322    \endcode
1323 */
1324 template< typename VT  // Type of the dense vector
1325         , bool TF >    // Transpose flag
decltype(auto)1326 inline decltype(auto) sign( const DenseVector<VT,TF>& dv )
1327 {
1328    BLAZE_FUNCTION_TRACE;
1329 
1330    return map( *dv, Sign() );
1331 }
1332 //*************************************************************************************************
1333 
1334 
1335 //*************************************************************************************************
1336 /*!\brief Applies the \a floor() function to each single element of the dense vector \a dv.
1337 // \ingroup dense_vector
1338 //
1339 // \param dv The input vector.
1340 // \return The resulting dense vector.
1341 //
1342 // This function applies the \a floor() function to each element of the input vector \a dv. The
1343 // function returns an expression representing this operation.\n
1344 // The following example demonstrates the use of the \a floor() function:
1345 
1346    \code
1347    blaze::DynamicVector<double> a, b;
1348    // ... Resizing and initialization
1349    b = floor( a );
1350    \endcode
1351 */
1352 template< typename VT  // Type of the dense vector
1353         , bool TF >    // Transpose flag
decltype(auto)1354 inline decltype(auto) floor( const DenseVector<VT,TF>& dv )
1355 {
1356    BLAZE_FUNCTION_TRACE;
1357 
1358    return map( *dv, Floor() );
1359 }
1360 //*************************************************************************************************
1361 
1362 
1363 //*************************************************************************************************
1364 /*!\brief Applies the \a ceil() function to each single element of the dense vector \a dv.
1365 // \ingroup dense_vector
1366 //
1367 // \param dv The input vector.
1368 // \return The resulting dense vector.
1369 //
1370 // This function applies the \a ceil() function to each element of the input vector \a dv. The
1371 // function returns an expression representing this operation.\n
1372 // The following example demonstrates the use of the \a ceil() function:
1373 
1374    \code
1375    blaze::DynamicVector<double> a, b;
1376    // ... Resizing and initialization
1377    b = ceil( a );
1378    \endcode
1379 */
1380 template< typename VT  // Type of the dense vector
1381         , bool TF >    // Transpose flag
decltype(auto)1382 inline decltype(auto) ceil( const DenseVector<VT,TF>& dv )
1383 {
1384    BLAZE_FUNCTION_TRACE;
1385 
1386    return map( *dv, Ceil() );
1387 }
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1392 /*!\brief Applies the \a trunc() function to each single element of the dense vector \a dv.
1393 // \ingroup dense_vector
1394 //
1395 // \param dv The input vector.
1396 // \return The resulting dense vector.
1397 //
1398 // This function applies the \a trunc() function to each element of the input vector \a dv. The
1399 // function returns an expression representing this operation.\n
1400 // The following example demonstrates the use of the \a trunc() function:
1401 
1402    \code
1403    blaze::DynamicVector<double> a, b;
1404    // ... Resizing and initialization
1405    b = trunc( a );
1406    \endcode
1407 */
1408 template< typename VT  // Type of the dense vector
1409         , bool TF >    // Transpose flag
decltype(auto)1410 inline decltype(auto) trunc( const DenseVector<VT,TF>& dv )
1411 {
1412    BLAZE_FUNCTION_TRACE;
1413 
1414    return map( *dv, Trunc() );
1415 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1420 /*!\brief Applies the \a round() function to each single element of the dense vector \a dv.
1421 // \ingroup dense_vector
1422 //
1423 // \param dv The input vector.
1424 // \return The resulting dense vector.
1425 //
1426 // This function applies the \a round() function to each element of the input vector \a dv. The
1427 // function returns an expression representing this operation.\n
1428 // The following example demonstrates the use of the \a round() function:
1429 
1430    \code
1431    blaze::DynamicVector<double> a, b;
1432    // ... Resizing and initialization
1433    b = round( a );
1434    \endcode
1435 */
1436 template< typename VT  // Type of the dense vector
1437         , bool TF >    // Transpose flag
decltype(auto)1438 inline decltype(auto) round( const DenseVector<VT,TF>& dv )
1439 {
1440    BLAZE_FUNCTION_TRACE;
1441 
1442    return map( *dv, Round() );
1443 }
1444 //*************************************************************************************************
1445 
1446 
1447 //*************************************************************************************************
1448 /*!\brief Returns a vector containing the complex conjugate of each single element of \a dv.
1449 // \ingroup dense_vector
1450 //
1451 // \param dv The input vector.
1452 // \return The complex conjugate of each single element of \a dv.
1453 //
1454 // The \a conj() function calculates the complex conjugate of each element of the input vector
1455 // \a dv. The function returns an expression representing this operation.\n
1456 // The following example demonstrates the use of the \a conj() function:
1457 
1458    \code
1459    blaze::DynamicVector< complex<double> > a, b;
1460    // ... Resizing and initialization
1461    b = conj( a );
1462    \endcode
1463 */
1464 template< typename VT  // Type of the dense vector
1465         , bool TF >    // Transpose flag
decltype(auto)1466 inline decltype(auto) conj( const DenseVector<VT,TF>& dv )
1467 {
1468    BLAZE_FUNCTION_TRACE;
1469 
1470    return map( *dv, Conj() );
1471 }
1472 //*************************************************************************************************
1473 
1474 
1475 //*************************************************************************************************
1476 /*!\brief Returns the conjugate transpose vector of \a dv.
1477 // \ingroup dense_vector
1478 //
1479 // \param dv The input vector.
1480 // \return The conjugate transpose of \a dv.
1481 //
1482 // The \a ctrans() function returns an expression representing the conjugate transpose (also
1483 // called adjoint matrix, Hermitian conjugate matrix or transjugate matrix) of the given input
1484 // vector \a dv.\n
1485 // The following example demonstrates the use of the \a ctrans() function:
1486 
1487    \code
1488    blaze::DynamicVector< complex<double> > a, b;
1489    // ... Resizing and initialization
1490    b = ctrans( a );
1491    \endcode
1492 
1493 // Note that the \a ctrans() function has the same effect as manually applying the \a conj() and
1494 // \a trans function in any order:
1495 
1496    \code
1497    b = trans( conj( a ) );  // Computing the conjugate transpose vector
1498    b = conj( trans( a ) );  // Computing the conjugate transpose vector
1499    \endcode
1500 */
1501 template< typename VT  // Type of the dense vector
1502         , bool TF >    // Transpose flag
decltype(auto)1503 inline decltype(auto) ctrans( const DenseVector<VT,TF>& dv )
1504 {
1505    BLAZE_FUNCTION_TRACE;
1506 
1507    return trans( conj( *dv ) );
1508 }
1509 //*************************************************************************************************
1510 
1511 
1512 //*************************************************************************************************
1513 /*!\brief Returns a vector containing the real part of each single element of \a dv.
1514 // \ingroup dense_vector
1515 //
1516 // \param dv The input vector.
1517 // \return The real part of each single element of \a dv.
1518 //
1519 // The \a real() function calculates the real part of each element of the input vector \a dv.
1520 // The function returns an expression representing this operation.\n
1521 // The following example demonstrates the use of the \a real() function:
1522 
1523    \code
1524    blaze::DynamicVector<double> a, b;
1525    // ... Resizing and initialization
1526    b = real( a );
1527    \endcode
1528 */
1529 template< typename VT  // Type of the dense vector
1530         , bool TF >    // Transpose flag
decltype(auto)1531 inline decltype(auto) real( const DenseVector<VT,TF>& dv )
1532 {
1533    BLAZE_FUNCTION_TRACE;
1534 
1535    return map( *dv, Real() );
1536 }
1537 //*************************************************************************************************
1538 
1539 
1540 //*************************************************************************************************
1541 /*!\brief Returns a vector containing the imaginary part of each single element of \a dv.
1542 // \ingroup dense_vector
1543 //
1544 // \param dv The input vector.
1545 // \return The imaginary part of each single element of \a dv.
1546 //
1547 // The \a imag() function calculates the imaginary part of each element of the input vector \a dv.
1548 // The function returns an expression representing this operation.\n
1549 // The following example demonstrates the use of the \a imag() function:
1550 
1551    \code
1552    blaze::DynamicVector<double> a, b;
1553    // ... Resizing and initialization
1554    b = imag( a );
1555    \endcode
1556 */
1557 template< typename VT  // Type of the dense vector
1558         , bool TF >    // Transpose flag
decltype(auto)1559 inline decltype(auto) imag( const DenseVector<VT,TF>& dv )
1560 {
1561    BLAZE_FUNCTION_TRACE;
1562 
1563    return map( *dv, Imag() );
1564 }
1565 //*************************************************************************************************
1566 
1567 
1568 //*************************************************************************************************
1569 /*!\brief Returns a vector containing the phase angle of each single element of \a dv.
1570 // \ingroup dense_vector
1571 //
1572 // \param dv The input vector.
1573 // \return The phase angle of each single element of \a dv.
1574 //
1575 // The \a arg() function calculates the phase angle of each element of the input vector \a dv.
1576 // The function returns an expression representing this operation.\n
1577 // The following example demonstrates the use of the \a arg() function:
1578 
1579    \code
1580    blaze::DynamicVector<double> a, b;
1581    // ... Resizing and initialization
1582    b = arg( a );
1583    \endcode
1584 */
1585 template< typename VT  // Type of the dense vector
1586         , bool TF >    // Transpose flag
decltype(auto)1587 inline decltype(auto) arg( const DenseVector<VT,TF>& dv )
1588 {
1589    BLAZE_FUNCTION_TRACE;
1590 
1591    return map( *dv, Arg() );
1592 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1597 /*!\brief Computes the square root of each single element of the dense vector \a dv.
1598 // \ingroup dense_vector
1599 //
1600 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1601 // \return The square root of each single element of \a dv.
1602 //
1603 // The \a sqrt() function computes the square root of each element of the input vector \a dv.
1604 // The function returns an expression representing this operation.\n
1605 // The following example demonstrates the use of the \a sqrt() function:
1606 
1607    \code
1608    blaze::DynamicVector<double> a, b;
1609    // ... Resizing and initialization
1610    b = sqrt( a );
1611    \endcode
1612 
1613 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1614 // performed to assert this precondition!
1615 */
1616 template< typename VT  // Type of the dense vector
1617         , bool TF >    // Transpose flag
decltype(auto)1618 inline decltype(auto) sqrt( const DenseVector<VT,TF>& dv )
1619 {
1620    BLAZE_FUNCTION_TRACE;
1621 
1622    return map( *dv, Sqrt() );
1623 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1628 /*!\brief Computes the inverse square root of each single element of the dense vector \a dv.
1629 // \ingroup dense_vector
1630 //
1631 // \param dv The input vector; all elements must be in the range \f$(0..\infty)\f$.
1632 // \return The inverse square root of each single element of \a dv.
1633 //
1634 // The \a invsqrt() function computes the inverse square root of each element of the input vector
1635 // \a dv. The function returns an expression representing this operation.\n
1636 // The following example demonstrates the use of the \a invsqrt() function:
1637 
1638    \code
1639    blaze::DynamicVector<double> a, b;
1640    // ... Resizing and initialization
1641    b = invsqrt( a );
1642    \endcode
1643 
1644 // \note All elements are expected to be in the range \f$(0..\infty)\f$. No runtime checks are
1645 // performed to assert this precondition!
1646 */
1647 template< typename VT  // Type of the dense vector
1648         , bool TF >    // Transpose flag
decltype(auto)1649 inline decltype(auto) invsqrt( const DenseVector<VT,TF>& dv )
1650 {
1651    BLAZE_FUNCTION_TRACE;
1652 
1653    return map( *dv, InvSqrt() );
1654 }
1655 //*************************************************************************************************
1656 
1657 
1658 //*************************************************************************************************
1659 /*!\brief Computes the cubic root of each single element of the dense vector \a dv.
1660 // \ingroup dense_vector
1661 //
1662 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1663 // \return The cubic root of each single element of \a dv.
1664 //
1665 // The \a cbrt() function computes the cubic root of each element of the input vector \a dv. The
1666 // function returns an expression representing this operation.\n
1667 // The following example demonstrates the use of the \a cbrt() function:
1668 
1669    \code
1670    blaze::DynamicVector<double> a, b;
1671    // ... Resizing and initialization
1672    b = cbrt( a );
1673    \endcode
1674 
1675 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1676 // performed to assert this precondition!
1677 */
1678 template< typename VT  // Type of the dense vector
1679         , bool TF >    // Transpose flag
decltype(auto)1680 inline decltype(auto) cbrt( const DenseVector<VT,TF>& dv )
1681 {
1682    BLAZE_FUNCTION_TRACE;
1683 
1684    return map( *dv, Cbrt() );
1685 }
1686 //*************************************************************************************************
1687 
1688 
1689 //*************************************************************************************************
1690 /*!\brief Computes the inverse cubic root of each single element of the dense vector \a dv.
1691 // \ingroup dense_vector
1692 //
1693 // \param dv The input vector; all elements must be in the range \f$(0..\infty)\f$.
1694 // \return The inverse cubic root of each single element of \a dv.
1695 //
1696 // The \a invcbrt() function computes the inverse cubic root of each element of the input vector
1697 // \a dv. The function returns an expression representing this operation.\n
1698 // The following example demonstrates the use of the \a invcbrt() function:
1699 
1700    \code
1701    blaze::DynamicVector<double> a, b;
1702    // ... Resizing and initialization
1703    b = invcbrt( a );
1704    \endcode
1705 
1706 // \note All elements are expected to be in the range \f$(0..\infty)\f$. No runtime checks are
1707 // performed to assert this precondition!
1708 */
1709 template< typename VT  // Type of the dense vector
1710         , bool TF >    // Transpose flag
decltype(auto)1711 inline decltype(auto) invcbrt( const DenseVector<VT,TF>& dv )
1712 {
1713    BLAZE_FUNCTION_TRACE;
1714 
1715    return map( *dv, InvCbrt() );
1716 }
1717 //*************************************************************************************************
1718 
1719 
1720 //*************************************************************************************************
1721 /*!\brief Restricts each single element of the dense vector \a dv to the range \f$[min..max]\f$.
1722 // \ingroup dense_vector
1723 //
1724 // \param dv The input vector.
1725 // \param min The lower delimiter.
1726 // \param max The upper delimiter.
1727 // \return The vector with restricted elements.
1728 //
1729 // The \a clamp() function restricts each element of the input vector \a dv to the range
1730 // \f$[min..max]\f$. The function returns an expression representing this operation.\n
1731 // The following example demonstrates the use of the \a clamp() function:
1732 
1733    \code
1734    blaze::DynamicVector<double> a, b;
1735    // ... Resizing and initialization
1736    b = clamp( a, -1.0, 1.0 );
1737    \endcode
1738 */
1739 template< typename VT    // Type of the dense vector
1740         , bool TF        // Transpose flag
1741         , typename DT >  // Type of the delimiters
decltype(auto)1742 inline decltype(auto) clamp( const DenseVector<VT,TF>& dv, const DT& min, const DT& max )
1743 {
1744    BLAZE_FUNCTION_TRACE;
1745 
1746    return map( *dv, bind2nd( bind3rd( Clamp(), max ), min ) );
1747 }
1748 //*************************************************************************************************
1749 
1750 
1751 //*************************************************************************************************
1752 /*!\brief Computes the exponential value for each single element of the dense vector \a dv.
1753 // \ingroup dense_vector
1754 //
1755 // \param dv The input vector.
1756 // \param exp The scalar exponent.
1757 // \return The exponential value of each single element of \a dv.
1758 //
1759 // The \a pow() function computes the exponential value for each element of the input vector
1760 // \a dv. The function returns an expression representing this operation.\n
1761 // The following example demonstrates the use of the \a pow() function:
1762 
1763    \code
1764    blaze::DynamicVector<double> a, b;
1765    // ... Resizing and initialization
1766    b = pow( a, 4.2 );
1767    \endcode
1768 */
1769 template< typename VT  // Type of the dense vector
1770         , bool TF      // Transpose flag
1771         , typename ST  // Type of the scalar exponent
1772         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1773 inline decltype(auto) pow( const DenseVector<VT,TF>& dv, ST exp )
1774 {
1775    BLAZE_FUNCTION_TRACE;
1776 
1777    using ET = ElementType_t<VT>;
1778    using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MultTrait_t<ET,ST>, ST >;
1779    return map( *dv, blaze::bind2nd( Pow(), ScalarType( exp ) ) );
1780 }
1781 //*************************************************************************************************
1782 
1783 
1784 //*************************************************************************************************
1785 /*!\brief Computes \f$ e^x \f$ for each single element of the dense vector \a dv.
1786 // \ingroup dense_vector
1787 //
1788 // \param dv The input vector.
1789 // \return The resulting dense vector.
1790 //
1791 // The \a exp() function computes \f$ e^x \f$ for each element of the input vector \a dv. The
1792 // function returns an expression representing this operation.\n
1793 // The following example demonstrates the use of the \a exp() function:
1794 
1795    \code
1796    blaze::DynamicVector<double> a, b;
1797    // ... Resizing and initialization
1798    b = exp( a );
1799    \endcode
1800 */
1801 template< typename VT  // Type of the dense vector
1802         , bool TF >    // Transpose flag
decltype(auto)1803 inline decltype(auto) exp( const DenseVector<VT,TF>& dv )
1804 {
1805    BLAZE_FUNCTION_TRACE;
1806 
1807    return map( *dv, Exp() );
1808 }
1809 //*************************************************************************************************
1810 
1811 
1812 //*************************************************************************************************
1813 /*!\brief Computes \f$ 2^x \f$ for each single element of the dense vector \a dv.
1814 // \ingroup dense_vector
1815 //
1816 // \param dv The input vector.
1817 // \return The resulting dense vector.
1818 //
1819 // The \a exp2() function computes \f$ 2^x \f$ for each element of the input vector \a dv. The
1820 // function returns an expression representing this operation.\n
1821 // The following example demonstrates the use of the \a exp2() function:
1822 
1823    \code
1824    blaze::DynamicVector<double> a, b;
1825    // ... Resizing and initialization
1826    b = exp2( a );
1827    \endcode
1828 */
1829 template< typename VT  // Type of the dense vector
1830         , bool TF >    // Transpose flag
decltype(auto)1831 inline decltype(auto) exp2( const DenseVector<VT,TF>& dv )
1832 {
1833    BLAZE_FUNCTION_TRACE;
1834 
1835    return map( *dv, Exp2() );
1836 }
1837 //*************************************************************************************************
1838 
1839 
1840 //*************************************************************************************************
1841 /*!\brief Computes \f$ 10^x \f$ for each single element of the dense vector \a dv.
1842 // \ingroup dense_vector
1843 //
1844 // \param dv The input vector.
1845 // \return The resulting dense vector.
1846 //
1847 // The \a exp10() function computes \f$ 10^x \f$ for each element of the input vector \a dv. The
1848 // function returns an expression representing this operation.\n
1849 // The following example demonstrates the use of the \a exp10() function:
1850 
1851    \code
1852    blaze::DynamicVector<double> a, b;
1853    // ... Resizing and initialization
1854    b = exp10( a );
1855    \endcode
1856 */
1857 template< typename VT  // Type of the dense vector
1858         , bool TF >    // Transpose flag
decltype(auto)1859 inline decltype(auto) exp10( const DenseVector<VT,TF>& dv )
1860 {
1861    BLAZE_FUNCTION_TRACE;
1862 
1863    return map( *dv, Exp10() );
1864 }
1865 //*************************************************************************************************
1866 
1867 
1868 //*************************************************************************************************
1869 /*!\brief Computes the natural logarithm for each single element of the dense vector \a dv.
1870 // \ingroup dense_vector
1871 //
1872 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1873 // \return The natural logarithm of each single element of \a dv.
1874 //
1875 // The \a log() function computes natural logarithm for each element of the input vector \a dv.
1876 // The function returns an expression representing this operation.\n
1877 // The following example demonstrates the use of the \a log() function:
1878 
1879    \code
1880    blaze::DynamicVector<double> a, b;
1881    // ... Resizing and initialization
1882    b = log( a );
1883    \endcode
1884 
1885 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1886 // performed to assert this precondition!
1887 */
1888 template< typename VT  // Type of the dense vector
1889         , bool TF >    // Transpose flag
decltype(auto)1890 inline decltype(auto) log( const DenseVector<VT,TF>& dv )
1891 {
1892    BLAZE_FUNCTION_TRACE;
1893 
1894    return map( *dv, Log() );
1895 }
1896 //*************************************************************************************************
1897 
1898 
1899 //*************************************************************************************************
1900 /*!\brief Computes the binary logarithm for each single element of the dense vector \a dv.
1901 // \ingroup dense_vector
1902 //
1903 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1904 // \return The binary logarithm of each single element of \a dv.
1905 //
1906 // The \a log2() function computes binary logarithm for each element of the input vector \a dv.
1907 // The function returns an expression representing this operation.\n
1908 // The following example demonstrates the use of the \a log2() function:
1909 
1910    \code
1911    blaze::DynamicVector<double> a, b;
1912    // ... Resizing and initialization
1913    b = log2( a );
1914    \endcode
1915 
1916 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1917 // performed to assert this precondition!
1918 */
1919 template< typename VT  // Type of the dense vector
1920         , bool TF >    // Transpose flag
decltype(auto)1921 inline decltype(auto) log2( const DenseVector<VT,TF>& dv )
1922 {
1923    BLAZE_FUNCTION_TRACE;
1924 
1925    return map( *dv, Log2() );
1926 }
1927 //*************************************************************************************************
1928 
1929 
1930 //*************************************************************************************************
1931 /*!\brief Computes the common logarithm for each single element of the dense vector \a dv.
1932 // \ingroup dense_vector
1933 //
1934 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1935 // \return The common logarithm of each single element of \a dv.
1936 //
1937 // The \a log10() function computes common logarithm for each element of the input vector \a dv.
1938 // The function returns an expression representing this operation.\n
1939 // The following example demonstrates the use of the \a log10() function:
1940 
1941    \code
1942    blaze::DynamicVector<double> a, b;
1943    // ... Resizing and initialization
1944    b = log10( a );
1945    \endcode
1946 
1947 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1948 // performed to assert this precondition!
1949 */
1950 template< typename VT  // Type of the dense vector
1951         , bool TF >    // Transpose flag
decltype(auto)1952 inline decltype(auto) log10( const DenseVector<VT,TF>& dv )
1953 {
1954    BLAZE_FUNCTION_TRACE;
1955 
1956    return map( *dv, Log10() );
1957 }
1958 //*************************************************************************************************
1959 
1960 
1961 //*************************************************************************************************
1962 /*!\brief Computes the natural logarithm of x+1 for each single element of the dense vector \a dv.
1963 // \ingroup dense_vector
1964 //
1965 // \param dv The input vector; all elements must be in the range \f$[-1..\infty)\f$.
1966 // \return The natural logarithm of x+1 of each single element of \a dv.
1967 //
1968 // The \a log1p() function computes the natural logarithm of x+1 for each element of the input
1969 // vector \a dv. This may be preferred over the natural logarithm for higher precision computing
1970 // the natural logarithm of a quantity very close to 1. The function returns an expression
1971 // representing this operation.\n
1972 // The following example demonstrates the use of the \a log1p() function:
1973 
1974    \code
1975    blaze::DynamicVector<double> a, b;
1976    // ... Resizing and initialization
1977    b = log1p( a );
1978    \endcode
1979 
1980 // \note All elements are expected to be in the range \f$[-1..\infty)\f$. No runtime checks are
1981 // performed to assert this precondition!
1982 */
1983 template< typename VT  // Type of the dense vector
1984         , bool TF >    // Transpose flag
decltype(auto)1985 inline decltype(auto) log1p( const DenseVector<VT,TF>& dv )
1986 {
1987    BLAZE_FUNCTION_TRACE;
1988 
1989    return map( *dv, Log1p() );
1990 }
1991 //*************************************************************************************************
1992 
1993 
1994 //*************************************************************************************************
1995 /*!\brief Computes the natural logarithm of the absolute value of the gamma function for each
1996 //        single element of the dense vector \a dv.
1997 // \ingroup dense_vector
1998 //
1999 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
2000 // \return The natural logarithm of the absolute value of the gamma function of each single element of \a dv.
2001 //
2002 // The \a lgamma() function computes the natural logarithm of the absolute value of the gamma
2003 // function for each element of the input vector \a dv. The function returns an expression
2004 // representing this operation.\n
2005 // The following example demonstrates the use of the \a lgamma() function:
2006 
2007    \code
2008    blaze::DynamicVector<double> a, b;
2009    // ... Resizing and initialization
2010    b = lgamma( a );
2011    \endcode
2012 
2013 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
2014 // performed to assert this precondition!
2015 */
2016 template< typename VT  // Type of the dense vector
2017         , bool SO >    // Storage order
decltype(auto)2018 inline decltype(auto) lgamma( const DenseVector<VT,SO>& dv )
2019 {
2020    BLAZE_FUNCTION_TRACE;
2021 
2022    return map( *dv, LGamma() );
2023 }
2024 //*************************************************************************************************
2025 
2026 
2027 //*************************************************************************************************
2028 /*!\brief Computes the sine for each single element of the dense vector \a dv.
2029 // \ingroup dense_vector
2030 //
2031 // \param dv The input vector.
2032 // \return The sine of each single element of \a dv.
2033 //
2034 // The \a sin() function computes the sine for each element of the input vector \a dv. The
2035 // function returns an expression representing this operation.\n
2036 // The following example demonstrates the use of the \a sin() function:
2037 
2038    \code
2039    blaze::DynamicVector<double> a, b;
2040    // ... Resizing and initialization
2041    b = sin( a );
2042    \endcode
2043 */
2044 template< typename VT  // Type of the dense vector
2045         , bool TF >    // Transpose flag
decltype(auto)2046 inline decltype(auto) sin( const DenseVector<VT,TF>& dv )
2047 {
2048    BLAZE_FUNCTION_TRACE;
2049 
2050    return map( *dv, Sin() );
2051 }
2052 //*************************************************************************************************
2053 
2054 
2055 //*************************************************************************************************
2056 /*!\brief Computes the inverse sine for each single element of the dense vector \a dv.
2057 // \ingroup dense_vector
2058 //
2059 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2060 // \return The inverse sine of each single element of \a dv.
2061 //
2062 // The \a asin() function computes the inverse sine for each element of the input vector \a dv.
2063 // The function returns an expression representing this operation.\n
2064 // The following example demonstrates the use of the \a asin() function:
2065 
2066    \code
2067    blaze::DynamicVector<double> a, b;
2068    // ... Resizing and initialization
2069    b = asin( a );
2070    \endcode
2071 
2072 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2073 // performed to assert this precondition!
2074 */
2075 template< typename VT  // Type of the dense vector
2076         , bool TF >    // Transpose flag
decltype(auto)2077 inline decltype(auto) asin( const DenseVector<VT,TF>& dv )
2078 {
2079    BLAZE_FUNCTION_TRACE;
2080 
2081    return map( *dv, Asin() );
2082 }
2083 //*************************************************************************************************
2084 
2085 
2086 //*************************************************************************************************
2087 /*!\brief Computes the hyperbolic sine for each single element of the dense vector \a dv.
2088 // \ingroup dense_vector
2089 //
2090 // \param dv The input vector.
2091 // \return The hyperbolic sine of each single element of \a dv.
2092 //
2093 // The \a sinh() function computes the hyperbolic sine for each element of the input vector \a dv.
2094 // The function returns an expression representing this operation.\n
2095 // The following example demonstrates the use of the \a sinh() function:
2096 
2097    \code
2098    blaze::DynamicVector<double> a, b;
2099    // ... Resizing and initialization
2100    b = sinh( a );
2101    \endcode
2102 */
2103 template< typename VT  // Type of the dense vector
2104         , bool TF >    // Transpose flag
decltype(auto)2105 inline decltype(auto) sinh( const DenseVector<VT,TF>& dv )
2106 {
2107    BLAZE_FUNCTION_TRACE;
2108 
2109    return map( *dv, Sinh() );
2110 }
2111 //*************************************************************************************************
2112 
2113 
2114 //*************************************************************************************************
2115 /*!\brief Computes the inverse hyperbolic sine for each single element of the dense vector \a dv.
2116 // \ingroup dense_vector
2117 //
2118 // \param dv The input vector.
2119 // \return The inverse hyperbolic sine of each single element of \a dv.
2120 //
2121 // The \a asinh() function computes the inverse hyperbolic sine for each element of the input
2122 // vector \a dv. The function returns an expression representing this operation.\n
2123 // The following example demonstrates the use of the \a asinh() function:
2124 
2125    \code
2126    blaze::DynamicVector<double> a, b;
2127    // ... Resizing and initialization
2128    b = asinh( a );
2129    \endcode
2130 */
2131 template< typename VT  // Type of the dense vector
2132         , bool TF >    // Transpose flag
decltype(auto)2133 inline decltype(auto) asinh( const DenseVector<VT,TF>& dv )
2134 {
2135    BLAZE_FUNCTION_TRACE;
2136 
2137    return map( *dv, Asinh() );
2138 }
2139 //*************************************************************************************************
2140 
2141 
2142 //*************************************************************************************************
2143 /*!\brief Computes the cosine for each single element of the dense vector \a dv.
2144 // \ingroup dense_vector
2145 //
2146 // \param dv The input vector.
2147 // \return The cosine of each single element of \a dv.
2148 //
2149 // The \a cos() function computes the cosine for each element of the input vector \a dv. The
2150 // function returns an expression representing this operation.\n
2151 // The following example demonstrates the use of the \a cos() function:
2152 
2153    \code
2154    blaze::DynamicVector<double> a, b;
2155    // ... Resizing and initialization
2156    b = cos( a );
2157    \endcode
2158 */
2159 template< typename VT  // Type of the dense vector
2160         , bool TF >    // Transpose flag
decltype(auto)2161 inline decltype(auto) cos( const DenseVector<VT,TF>& dv )
2162 {
2163    BLAZE_FUNCTION_TRACE;
2164 
2165    return map( *dv, Cos() );
2166 }
2167 //*************************************************************************************************
2168 
2169 
2170 //*************************************************************************************************
2171 /*!\brief Computes the inverse cosine for each single element of the dense vector \a dv.
2172 // \ingroup dense_vector
2173 //
2174 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2175 // \return The inverse cosine of each single element of \a dv.
2176 //
2177 // The \a acos() function computes the inverse cosine for each element of the input vector \a dv.
2178 // The function returns an expression representing this operation.\n
2179 // The following example demonstrates the use of the \a acos() function:
2180 
2181    \code
2182    blaze::DynamicVector<double> a, b;
2183    // ... Resizing and initialization
2184    b = acos( a );
2185    \endcode
2186 
2187 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2188 // performed to assert this precondition!
2189 */
2190 template< typename VT  // Type of the dense vector
2191         , bool TF >    // Transpose flag
decltype(auto)2192 inline decltype(auto) acos( const DenseVector<VT,TF>& dv )
2193 {
2194    BLAZE_FUNCTION_TRACE;
2195 
2196    return map( *dv, Acos() );
2197 }
2198 //*************************************************************************************************
2199 
2200 
2201 //*************************************************************************************************
2202 /*!\brief Computes the hyperbolic cosine for each single element of the dense vector \a dv.
2203 // \ingroup dense_vector
2204 //
2205 // \param dv The input vector.
2206 // \return The hyperbolic cosine of each single element of \a dv.
2207 //
2208 // The \a cosh() function computes the hyperbolic cosine for each element of the input vector
2209 // \a dv. The function returns an expression representing this operation.\n
2210 // The following example demonstrates the use of the \a cosh() function:
2211 
2212    \code
2213    blaze::DynamicVector<double> a, b;
2214    // ... Resizing and initialization
2215    b = cosh( a );
2216    \endcode
2217 */
2218 template< typename VT  // Type of the dense vector
2219         , bool TF >    // Transpose flag
decltype(auto)2220 inline decltype(auto) cosh( const DenseVector<VT,TF>& dv )
2221 {
2222    BLAZE_FUNCTION_TRACE;
2223 
2224    return map( *dv, Cosh() );
2225 }
2226 //*************************************************************************************************
2227 
2228 
2229 //*************************************************************************************************
2230 /*!\brief Computes the inverse hyperbolic cosine for each single element of the dense vector \a dv.
2231 // \ingroup dense_vector
2232 //
2233 // \param dv The input vector; all elements must be in the range \f$[1..\infty)\f$.
2234 // \return The inverse hyperbolic cosine of each single element of \a dv.
2235 //
2236 // The \a acosh() function computes the inverse hyperbolic cosine for each element of the input
2237 // vector \a dv. The function returns an expression representing this operation.\n
2238 // The following example demonstrates the use of the \a acosh() function:
2239 
2240    \code
2241    blaze::DynamicVector<double> a, b;
2242    // ... Resizing and initialization
2243    b = acosh( a );
2244    \endcode
2245 
2246 // \note All elements are expected to be in the range \f$[1..\infty)\f$. No runtime checks are
2247 // performed to assert this precondition!
2248 */
2249 template< typename VT  // Type of the dense vector
2250         , bool TF >    // Transpose flag
decltype(auto)2251 inline decltype(auto) acosh( const DenseVector<VT,TF>& dv )
2252 {
2253    BLAZE_FUNCTION_TRACE;
2254 
2255    return map( *dv, Acosh() );
2256 }
2257 //*************************************************************************************************
2258 
2259 
2260 //*************************************************************************************************
2261 /*!\brief Computes the tangent for each single element of the dense vector \a dv.
2262 // \ingroup dense_vector
2263 //
2264 // \param dv The input vector.
2265 // \return The tangent of each single element of \a dv.
2266 //
2267 // The \a tan() function computes the tangent for each element of the input vector \a dv. The
2268 // function returns an expression representing this operation.\n
2269 // The following example demonstrates the use of the \a tan() function:
2270 
2271    \code
2272    blaze::DynamicVector<double> a, b;
2273    // ... Resizing and initialization
2274    b = tan( a );
2275    \endcode
2276 */
2277 template< typename VT  // Type of the dense vector
2278         , bool TF >    // Transpose flag
decltype(auto)2279 inline decltype(auto) tan( const DenseVector<VT,TF>& dv )
2280 {
2281    BLAZE_FUNCTION_TRACE;
2282 
2283    return map( *dv, Tan() );
2284 }
2285 //*************************************************************************************************
2286 
2287 
2288 //*************************************************************************************************
2289 /*!\brief Computes the inverse tangent for each single element of the dense vector \a dv.
2290 // \ingroup dense_vector
2291 //
2292 // \param dv The input vector.
2293 // \return The inverse tangent of each single element of \a dv.
2294 //
2295 // The \a atan() function computes the inverse tangent for each element of the input vector \a dv.
2296 // The function returns an expression representing this operation.\n
2297 // The following example demonstrates the use of the \a atan() function:
2298 
2299    \code
2300    blaze::DynamicVector<double> a, b;
2301    // ... Resizing and initialization
2302    b = atan( a );
2303    \endcode
2304 */
2305 template< typename VT  // Type of the dense vector
2306         , bool TF >    // Transpose flag
decltype(auto)2307 inline decltype(auto) atan( const DenseVector<VT,TF>& dv )
2308 {
2309    BLAZE_FUNCTION_TRACE;
2310 
2311    return map( *dv, Atan() );
2312 }
2313 //*************************************************************************************************
2314 
2315 
2316 //*************************************************************************************************
2317 /*!\brief Computes the hyperbolic tangent for each single element of the dense vector \a dv.
2318 // \ingroup dense_vector
2319 //
2320 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2321 // \return The hyperbolic tangent of each single element of \a dv.
2322 //
2323 // The \a tanh() function computes the hyperbolic tangent for each element of the input vector
2324 // \a dv. The function returns an expression representing this operation.\n
2325 // The following example demonstrates the use of the \a tanh() function:
2326 
2327    \code
2328    blaze::DynamicVector<double> a, b;
2329    // ... Resizing and initialization
2330    b = tanh( a );
2331    \endcode
2332 
2333 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2334 // performed to assert this precondition!
2335 */
2336 template< typename VT  // Type of the dense vector
2337         , bool TF >    // Transpose flag
decltype(auto)2338 inline decltype(auto) tanh( const DenseVector<VT,TF>& dv )
2339 {
2340    BLAZE_FUNCTION_TRACE;
2341 
2342    return map( *dv, Tanh() );
2343 }
2344 //*************************************************************************************************
2345 
2346 
2347 //*************************************************************************************************
2348 /*!\brief Computes the inverse hyperbolic tangent for each single element of the dense vector \a dv.
2349 // \ingroup dense_vector
2350 //
2351 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2352 // \return The inverse hyperbolic tangent of each single element of \a dv.
2353 //
2354 // The \a atanh() function computes the inverse hyperbolic tangent for each element of the input
2355 // vector \a dv. The function returns an expression representing this operation.\n
2356 // The following example demonstrates the use of the \a atanh() function:
2357 
2358    \code
2359    blaze::DynamicVector<double> a, b;
2360    // ... Resizing and initialization
2361    b = atanh( a );
2362    \endcode
2363 
2364 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2365 // performed to assert this precondition!
2366 */
2367 template< typename VT  // Type of the dense vector
2368         , bool TF >    // Transpose flag
decltype(auto)2369 inline decltype(auto) atanh( const DenseVector<VT,TF>& dv )
2370 {
2371    BLAZE_FUNCTION_TRACE;
2372 
2373    return map( *dv, Atanh() );
2374 }
2375 //*************************************************************************************************
2376 
2377 
2378 //*************************************************************************************************
2379 /*!\brief Computes the error function for each single element of the dense vector \a dv.
2380 // \ingroup dense_vector
2381 //
2382 // \param dv The input vector.
2383 // \return The error function of each single element of \a dv.
2384 //
2385 // The \a erf() function computes the error function for each element of the input vector \a dv.
2386 // The function returns an expression representing this operation.\n
2387 // The following example demonstrates the use of the \a erf() function:
2388 
2389    \code
2390    blaze::DynamicVector<double> a, b;
2391    // ... Resizing and initialization
2392    b = erf( a );
2393    \endcode
2394 */
2395 template< typename VT  // Type of the dense vector
2396         , bool TF >    // Transpose flag
decltype(auto)2397 inline decltype(auto) erf( const DenseVector<VT,TF>& dv )
2398 {
2399    BLAZE_FUNCTION_TRACE;
2400 
2401    return map( *dv, Erf() );
2402 }
2403 //*************************************************************************************************
2404 
2405 
2406 //*************************************************************************************************
2407 /*!\brief Computes the complementary error function for each single element of the dense vector \a dv.
2408 // \ingroup dense_vector
2409 //
2410 // \param dv The input vector.
2411 // \return The complementary error function of each single element of \a dv.
2412 //
2413 // The \a erfc() function computes the complementary error function for each element of the input
2414 // vector \a dv. The function returns an expression representing this operation.\n
2415 // The following example demonstrates the use of the \a erfc() function:
2416 
2417    \code
2418    blaze::DynamicVector<double> a, b;
2419    // ... Resizing and initialization
2420    b = erfc( a );
2421    \endcode
2422 */
2423 template< typename VT  // Type of the dense vector
2424         , bool TF >    // Transpose flag
decltype(auto)2425 inline decltype(auto) erfc( const DenseVector<VT,TF>& dv )
2426 {
2427    BLAZE_FUNCTION_TRACE;
2428 
2429    return map( *dv, Erfc() );
2430 }
2431 //*************************************************************************************************
2432 
2433 
2434 
2435 
2436 //=================================================================================================
2437 //
2438 //  GLOBAL RESTRUCTURING FUNCTIONS
2439 //
2440 //=================================================================================================
2441 
2442 //*************************************************************************************************
2443 /*! \cond BLAZE_INTERNAL */
2444 /*!\brief Absolute value function for absolute value dense vector expressions.
2445 // \ingroup dense_vector
2446 //
2447 // \param dv The absolute value dense vector expression.
2448 // \return The absolute value of each single element of \a dv.
2449 //
2450 // This function implements a performance optimized treatment of the absolute value operation
2451 // on a dense vector absolute value expression.
2452 */
2453 template< typename VT  // Type of the dense vector
2454         , bool TF >    // Transpose flag
decltype(auto)2455 inline decltype(auto) abs( const DVecMapExpr<VT,Abs,TF>& dv )
2456 {
2457    BLAZE_FUNCTION_TRACE;
2458 
2459    return dv;
2460 }
2461 /*! \endcond */
2462 //*************************************************************************************************
2463 
2464 
2465 //*************************************************************************************************
2466 /*! \cond BLAZE_INTERNAL */
2467 /*!\brief Applies the \a sign() function for dense vector \a sign() expressions.
2468 // \ingroup dense_vector
2469 //
2470 // \param dv The dense vector \a sign() expression.
2471 // \return The resulting dense vector.
2472 //
2473 // This function implements a performance optimized treatment of the \a sign() operation on a
2474 // dense vector \a sign() expression.
2475 */
2476 template< typename VT  // Type of the dense vector
2477         , bool TF >    // Transpose flag
decltype(auto)2478 inline decltype(auto) sign( const DVecMapExpr<VT,Sign,TF>& dv )
2479 {
2480    BLAZE_FUNCTION_TRACE;
2481 
2482    return dv;
2483 }
2484 /*! \endcond */
2485 //*************************************************************************************************
2486 
2487 
2488 //*************************************************************************************************
2489 /*! \cond BLAZE_INTERNAL */
2490 /*!\brief Applies the \a floor() function to a dense vector \a floor() expressions.
2491 // \ingroup dense_vector
2492 //
2493 // \param dv The dense vector \a floor() expression.
2494 // \return The resulting dense vector.
2495 //
2496 // This function implements a performance optimized treatment of the \a floor() operation on
2497 // a dense vector \a floor() expression.
2498 */
2499 template< typename VT  // Type of the dense vector
2500         , bool TF >    // Transpose flag
decltype(auto)2501 inline decltype(auto) floor( const DVecMapExpr<VT,Floor,TF>& dv )
2502 {
2503    BLAZE_FUNCTION_TRACE;
2504 
2505    return dv;
2506 }
2507 /*! \endcond */
2508 //*************************************************************************************************
2509 
2510 
2511 //*************************************************************************************************
2512 /*! \cond BLAZE_INTERNAL */
2513 /*!\brief Applies the \a ceil() function to a dense vector \a ceil() expressions.
2514 // \ingroup dense_vector
2515 //
2516 // \param dv The dense vector \a ceil() expression.
2517 // \return The resulting dense vector.
2518 //
2519 // This function implements a performance optimized treatment of the \a ceil() operation on
2520 // a dense vector \a ceil() expression.
2521 */
2522 template< typename VT  // Type of the dense vector
2523         , bool TF >    // Transpose flag
decltype(auto)2524 inline decltype(auto) ceil( const DVecMapExpr<VT,Ceil,TF>& dv )
2525 {
2526    BLAZE_FUNCTION_TRACE;
2527 
2528    return dv;
2529 }
2530 /*! \endcond */
2531 //*************************************************************************************************
2532 
2533 
2534 //*************************************************************************************************
2535 /*! \cond BLAZE_INTERNAL */
2536 /*!\brief Applies the \a trunc() function to a dense vector \a trunc() expressions.
2537 // \ingroup dense_vector
2538 //
2539 // \param dv The dense vector \a trunc() expression.
2540 // \return The resulting dense vector.
2541 //
2542 // This function implements a performance optimized treatment of the \a trunc() operation on
2543 // a dense vector \a trunc() expression.
2544 */
2545 template< typename VT  // Type of the dense vector
2546         , bool TF >    // Transpose flag
decltype(auto)2547 inline decltype(auto) trunc( const DVecMapExpr<VT,Trunc,TF>& dv )
2548 {
2549    BLAZE_FUNCTION_TRACE;
2550 
2551    return dv;
2552 }
2553 /*! \endcond */
2554 //*************************************************************************************************
2555 
2556 
2557 //*************************************************************************************************
2558 /*! \cond BLAZE_INTERNAL */
2559 /*!\brief Applies the \a round() function to a dense vector \a round() expressions.
2560 // \ingroup dense_vector
2561 //
2562 // \param dv The dense vector \a round() expression.
2563 // \return The resulting dense vector.
2564 //
2565 // This function implements a performance optimized treatment of the \a round() operation on
2566 // a dense vector \a round() expression.
2567 */
2568 template< typename VT  // Type of the dense vector
2569         , bool TF >    // Transpose flag
decltype(auto)2570 inline decltype(auto) round( const DVecMapExpr<VT,Round,TF>& dv )
2571 {
2572    BLAZE_FUNCTION_TRACE;
2573 
2574    return dv;
2575 }
2576 /*! \endcond */
2577 //*************************************************************************************************
2578 
2579 
2580 //*************************************************************************************************
2581 /*! \cond BLAZE_INTERNAL */
2582 /*!\brief Complex conjugate function for complex conjugate dense vector expressions.
2583 // \ingroup dense_vector
2584 //
2585 // \param dv The complex conjugate dense vector expression.
2586 // \return The original dense vector.
2587 //
2588 // This function implements a performance optimized treatment of the complex conjugate operation
2589 // on a dense vector complex conjugate expression. It returns an expression representing the
2590 // original dense vector:
2591 
2592    \code
2593    blaze::DynamicVector< complex<double> > a, b;
2594    // ... Resizing and initialization
2595    b = conj( conj( a ) );
2596    \endcode
2597 */
2598 template< typename VT  // Type of the dense vector
2599         , bool TF >    // Transpose flag
decltype(auto)2600 inline decltype(auto) conj( const DVecMapExpr<VT,Conj,TF>& dv )
2601 {
2602    BLAZE_FUNCTION_TRACE;
2603 
2604    return dv.operand();
2605 }
2606 /*! \endcond */
2607 //*************************************************************************************************
2608 
2609 
2610 //*************************************************************************************************
2611 /*! \cond BLAZE_INTERNAL */
2612 /*!\brief Complex conjugate function for conjugate transpose dense vector expressions.
2613 // \ingroup dense_vector
2614 //
2615 // \param dv The conjugate transpose dense vector expression.
2616 // \return The transpose dense vector.
2617 //
2618 // This function implements a performance optimized treatment of the complex conjugate operation
2619 // on a dense vector conjugate transpose expression. It returns an expression representing the
2620 // transpose of the dense vector:
2621 
2622    \code
2623    blaze::DynamicVector< complex<double> > a, b;
2624    // ... Resizing and initialization
2625    b = conj( ctrans( a ) );
2626    \endcode
2627 */
2628 template< typename VT  // Type of the dense vector
2629         , bool TF >    // Transpose flag
decltype(auto)2630 inline decltype(auto) conj( const DVecTransExpr<DVecMapExpr<VT,Conj,TF>,!TF>& dv )
2631 {
2632    BLAZE_FUNCTION_TRACE;
2633 
2634    return trans( dv.operand().operand() );
2635 }
2636 /*! \endcond */
2637 //*************************************************************************************************
2638 
2639 
2640 //*************************************************************************************************
2641 /*! \cond BLAZE_INTERNAL */
2642 /*!\brief Real part function for real part dense vector expressions.
2643 // \ingroup dense_vector
2644 //
2645 // \param dv The real part dense vector expression.
2646 // \return The real part of each single element of \a dv.
2647 //
2648 // This function implements a performance optimized treatment of the real part operation on
2649 // a dense vector real part expression.
2650 */
2651 template< typename VT  // Type of the dense vector
2652         , bool TF >    // Transpose flag
decltype(auto)2653 inline decltype(auto) real( const DVecMapExpr<VT,Real,TF>& dv )
2654 {
2655    BLAZE_FUNCTION_TRACE;
2656 
2657    return dv;
2658 }
2659 /*! \endcond */
2660 //*************************************************************************************************
2661 
2662 
2663 
2664 
2665 //=================================================================================================
2666 //
2667 //  GLOBAL ARITHMETIC OPERATORS
2668 //
2669 //=================================================================================================
2670 
2671 //*************************************************************************************************
2672 /*!\brief Addition operator for the addition of a dense vector and a scalar value
2673 //        (\f$ \vec{a}=\vec{b}+s \f$).
2674 // \ingroup dense_vector
2675 //
2676 // \param vec The left-hand side dense vector for the addition.
2677 // \param scalar The right-hand side scalar value for the addition.
2678 // \return The vector sum.
2679 //
2680 // This operator represents the elementwise addition of a dense vector and a uniform vector
2681 // represented by a scalar value:
2682 
2683    \code
2684    blaze::DynamicVector<double> a, b;
2685    // ... Resizing and initialization
2686    b = a + 1.25;
2687    \endcode
2688 
2689 // The operator returns an expression representing a dense vector of the higher-order element type
2690 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2691 // \a ST have to be supported by the AddTrait class template. Note that this operator only works
2692 // for scalar values of built-in data type.
2693 */
2694 template< typename VT  // Type of the left-hand side dense vector
2695         , bool TF      // Transpose flag of the left-hand side dense vector
2696         , typename ST  // Type of the right-hand side scalar
2697         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2698 inline decltype(auto) operator+( const DenseVector<VT,TF>& vec, ST scalar )
2699 {
2700    BLAZE_FUNCTION_TRACE;
2701 
2702    using ET = ElementType_t<VT>;
2703    using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, AddTrait_t<ET,ST>, ST >;
2704    return map( *vec, blaze::bind2nd( Add{}, ScalarType( scalar ) ) );
2705 }
2706 //*************************************************************************************************
2707 
2708 
2709 //*************************************************************************************************
2710 /*!\brief Addition operator for the addition of a scalar value and a dense vector
2711 //        (\f$ \vec{a}=s+\vec{b} \f$).
2712 // \ingroup dense_vector
2713 //
2714 // \param scalar The left-hand side scalar value for the addition.
2715 // \param vec The right-hand side dense vector for the addition.
2716 // \return The vector sum.
2717 //
2718 // This operator represents the elementwise addition of a uniform vector represented by a scalar
2719 // value and a dense vector:
2720 
2721    \code
2722    blaze::DynamicVector<double> a, b;
2723    // ... Resizing and initialization
2724    b = 1.25 + a;
2725    \endcode
2726 
2727 // The operator returns an expression representing a dense vector of the higher-order element type
2728 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2729 // \a ST have to be supported by the AddTrait class template. Note that this operator only works
2730 // for scalar values of built-in data type.
2731 */
2732 template< typename ST  // Type of the left-hand side scalar
2733         , typename VT  // Type of the right-hand side dense vector
2734         , bool TF      // Transpose flag of the right-hand side dense vector
2735         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2736 inline decltype(auto) operator+( ST scalar, const DenseVector<VT,TF>& vec )
2737 {
2738    BLAZE_FUNCTION_TRACE;
2739 
2740    using ET = ElementType_t<VT>;
2741    using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, AddTrait_t<ST,ET>, ST >;
2742    return map( *vec, blaze::bind1st( Add{}, ScalarType( scalar ) ) );
2743 }
2744 //*************************************************************************************************
2745 
2746 
2747 //*************************************************************************************************
2748 /*!\brief Subtraction operator for the subtraction of a dense vector and a scalar value
2749 //        (\f$ \vec{a}=\vec{b}-s \f$).
2750 // \ingroup dense_vector
2751 //
2752 // \param vec The left-hand side dense vector for the subtraction.
2753 // \param scalar The right-hand side scalar value for the subtraction.
2754 // \return The vector difference.
2755 //
2756 // This operator represents the elementwise subtraction of a uniform vector represented by a
2757 // scalar value from a dense vector:
2758 
2759    \code
2760    blaze::DynamicVector<double> a, b;
2761    // ... Resizing and initialization
2762    b = a - 1.25;
2763    \endcode
2764 
2765 // The operator returns an expression representing a dense vector of the higher-order element type
2766 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2767 // \a ST have to be supported by the SubTrait class template. Note that this operator only works
2768 // for scalar values of built-in data type.
2769 */
2770 template< typename VT  // Type of the left-hand side dense vector
2771         , bool TF      // Transpose flag of the left-hand side dense vector
2772         , typename ST  // Type of the right-hand side scalar
2773         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2774 inline decltype(auto) operator-( const DenseVector<VT,TF>& vec, ST scalar )
2775 {
2776    BLAZE_FUNCTION_TRACE;
2777 
2778    using ET = ElementType_t<VT>;
2779    using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, SubTrait_t<ET,ST>, ST >;
2780    return map( *vec, blaze::bind2nd( Sub{}, ScalarType( scalar ) ) );
2781 }
2782 //*************************************************************************************************
2783 
2784 
2785 //*************************************************************************************************
2786 /*!\brief Subtraction operator for the subtraction of a scalar value and a dense vector
2787 //        (\f$ \vec{a}=s-\vec{b} \f$).
2788 // \ingroup dense_vector
2789 //
2790 // \param scalar The left-hand side scalar value for the subtraction.
2791 // \param vec The right-hand side dense vector for the subtraction.
2792 // \return The vector difference.
2793 //
2794 // This operator represents the elementwise subtraction of a dense vector from a uniform vector
2795 // represented by a scalar value:
2796 
2797    \code
2798    blaze::DynamicVector<double> a, b;
2799    // ... Resizing and initialization
2800    b = 1.25 - a;
2801    \endcode
2802 
2803 // The operator returns an expression representing a dense vector of the higher-order element type
2804 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2805 // \a ST have to be supported by the SubTrait class template. Note that this operator only works
2806 // for scalar values of built-in data type.
2807 */
2808 template< typename ST  // Type of the left-hand side scalar
2809         , typename VT  // Type of the right-hand side dense vector
2810         , bool TF      // Transpose flag of the right-hand side dense vector
2811         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2812 inline decltype(auto) operator-( ST scalar, const DenseVector<VT,TF>& vec )
2813 {
2814    BLAZE_FUNCTION_TRACE;
2815 
2816    using ET = ElementType_t<VT>;
2817    using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, SubTrait_t<ST,ET>, ST >;
2818    return map( *vec, blaze::bind1st( Sub{}, ScalarType( scalar ) ) );
2819 }
2820 //*************************************************************************************************
2821 
2822 
2823 //*************************************************************************************************
2824 /*!\brief Division operator for the division of a scalar value and a dense vector
2825 //        (\f$ \vec{a}=s/\vec{b} \f$).
2826 // \ingroup dense_vector
2827 //
2828 // \param scalar The left-hand side scalar value for the division.
2829 // \param vec The right-hand side dense vector for the division.
2830 // \return The vector quotient.
2831 //
2832 // This operator represents the elementwise division of a uniform vector represented by a scalar
2833 // value and a dense vector:
2834 
2835    \code
2836    blaze::DynamicVector<double> a, b;
2837    // ... Resizing and initialization
2838    b = 1.25 / a;
2839    \endcode
2840 
2841 // The operator returns an expression representing a dense vector of the higher-order element type
2842 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2843 // \a ST have to be supported by the DivTrait class template. Note that this operator only works
2844 // for scalar values of built-in data type.
2845 */
2846 template< typename ST  // Type of the left-hand side scalar
2847         , typename VT  // Type of the right-hand side dense vector
2848         , bool TF      // Transpose flag of the right-hand side dense vector
2849         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2850 inline decltype(auto) operator/( ST scalar, const DenseVector<VT,TF>& vec )
2851 {
2852    BLAZE_FUNCTION_TRACE;
2853 
2854    using ET = ElementType_t<VT>;
2855    using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, DivTrait_t<ST,ET>, ST >;
2856    return map( *vec, blaze::bind1st( Div{}, ScalarType( scalar ) ) );
2857 }
2858 //*************************************************************************************************
2859 
2860 
2861 //*************************************************************************************************
2862 /*!\brief Left-shift operator for the uniform left-shift of a dense vector.
2863 // \ingroup dense_vector
2864 //
2865 // \param vec The dense vector for the uniform left-shift operation.
2866 // \param count The number of bits to shift all vector elements.
2867 // \return The resulting vector.
2868 //
2869 // This operator represents the uniform left-shift of all elements of a dense vector:
2870 
2871    \code
2872    blaze::DynamicVector<unsigned int> a, b;
2873    // ... Resizing and initialization
2874    b = a << 3;
2875    \endcode
2876 */
2877 template< typename VT  // Type of the dense vector
2878         , bool TF >    // Transpose flag
2879 inline decltype(auto) operator<<( const DenseVector<VT,TF>& vec, int count )
2880 {
2881    BLAZE_FUNCTION_TRACE;
2882 
2883    return map( *vec, ShiftLI( count ) );
2884 }
2885 //*************************************************************************************************
2886 
2887 
2888 //*************************************************************************************************
2889 /*!\brief Right-shift operator for the uniform right-shift of a dense vector.
2890 // \ingroup dense_vector
2891 //
2892 // \param vec The dense vector for the uniform right-shift operation.
2893 // \param count The number of bits to shift all vector elements.
2894 // \return The resulting vector.
2895 //
2896 // This operator represents the uniform right-shift of all elements of a dense vector:
2897 
2898    \code
2899    blaze::DynamicVector<unsigned int> a, b;
2900    // ... Resizing and initialization
2901    b = a >> 3;
2902    \endcode
2903 */
2904 template< typename VT  // Type of the dense vector
2905         , bool TF >    // Transpose flag
decltype(auto)2906 inline decltype(auto) operator>>( const DenseVector<VT,TF>& vec, int count )
2907 {
2908    BLAZE_FUNCTION_TRACE;
2909 
2910    return map( *vec, ShiftRI( count ) );
2911 }
2912 //*************************************************************************************************
2913 
2914 
2915 //*************************************************************************************************
2916 /*!\brief Bitwise AND operator for the bitwise AND of a dense vector and a scalar value.
2917 // \ingroup dense_vector
2918 //
2919 // \param vec The left-hand side dense vector for the bitwise AND.
2920 // \param scalar The right-hand side scalar value for the bitwise AND.
2921 // \return The resulting vector.
2922 //
2923 // This operator represents the bitwise AND of a scalar value with all elements of a dense vector:
2924 
2925    \code
2926    blaze::DynamicVector<unsigned int> a, b;
2927    // ... Resizing and initialization
2928    b = a & 7U;
2929    \endcode
2930 */
2931 template< typename VT  // Type of the left-hand side dense vector
2932         , bool TF      // Transpose flag
2933         , typename ST  // Type of the right-hand side scalar
2934         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)2935 inline decltype(auto) operator&( const DenseVector<VT,TF>& vec, ST scalar )
2936 {
2937    BLAZE_FUNCTION_TRACE;
2938 
2939    return map( *vec, blaze::bind2nd( Bitand{}, scalar ) );
2940 }
2941 //*************************************************************************************************
2942 
2943 
2944 //*************************************************************************************************
2945 /*!\brief Bitwise OR operator for the bitwise OR of a dense vector and a scalar value.
2946 // \ingroup dense_vector
2947 //
2948 // \param vec The left-hand side dense vector for the bitwise OR.
2949 // \param scalar The right-hand side scalar value for the bitwise OR.
2950 // \return The resulting vector.
2951 //
2952 // This operator represents the bitwise OR of a scalar value with all elements of a dense vector:
2953 
2954    \code
2955    blaze::DynamicVector<unsigned int> a, b;
2956    // ... Resizing and initialization
2957    b = a | 7U;
2958    \endcode
2959 */
2960 template< typename VT  // Type of the left-hand side dense vector
2961         , bool TF      // Transpose flag
2962         , typename ST  // Type of the right-hand side scalar
2963         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2964 inline decltype(auto) operator|( const DenseVector<VT,TF>& vec, ST scalar )
2965 {
2966    BLAZE_FUNCTION_TRACE;
2967 
2968    return map( *vec, blaze::bind2nd( Bitor{}, scalar ) );
2969 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2974 /*!\brief Bitwise XOR operator for the bitwise XOR of a dense vector and a scalar value.
2975 // \ingroup dense_vector
2976 //
2977 // \param vec The left-hand side dense vector for the bitwise XOR.
2978 // \param scalar The right-hand side scalar value for the bitwise XOR.
2979 // \return The resulting vector.
2980 //
2981 // This operator represents the bitwise XOR of a scalar value with all elements of a dense vector:
2982 
2983    \code
2984    blaze::DynamicVector<unsigned int> a, b;
2985    // ... Resizing and initialization
2986    b = a ^ 7U;
2987    \endcode
2988 */
2989 template< typename VT  // Type of the left-hand side dense vector
2990         , bool TF      // Transpose flag
2991         , typename ST  // Type of the right-hand side scalar
2992         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2993 inline decltype(auto) operator^( const DenseVector<VT,TF>& vec, ST scalar )
2994 {
2995    BLAZE_FUNCTION_TRACE;
2996 
2997    return map( *vec, blaze::bind2nd( Bitxor{}, scalar ) );
2998 }
2999 //*************************************************************************************************
3000 
3001 
3002 
3003 
3004 //=================================================================================================
3005 //
3006 //  GLOBAL LOGICAL OPERATORS
3007 //
3008 //=================================================================================================
3009 
3010 //*************************************************************************************************
3011 /*!\brief Logical NOT operator for the logical NOT of a dense vector.
3012 // \ingroup dense_vector
3013 //
3014 // \param vec The dense vector for the logical NOT.
3015 // \return The negated vector.
3016 //
3017 // This operator represents the logical NOT of all elements of a dense vector:
3018 
3019    \code
3020    blaze::DynamicVector<bool> a, b;
3021    // ... Resizing and initialization
3022    b = !a;
3023    \endcode
3024 */
3025 template< typename VT  // Type of the dense vector
3026         , bool TF >    // Transpose flag
3027 inline decltype(auto) operator!( const DenseVector<VT,TF>& vec )
3028 {
3029    BLAZE_FUNCTION_TRACE;
3030 
3031    return map( *vec, Not{} );
3032 }
3033 //*************************************************************************************************
3034 
3035 
3036 
3037 
3038 //=================================================================================================
3039 //
3040 //  ISALIGNED SPECIALIZATIONS
3041 //
3042 //=================================================================================================
3043 
3044 //*************************************************************************************************
3045 /*! \cond BLAZE_INTERNAL */
3046 template< typename VT, typename OP, bool TF >
3047 struct IsAligned< DVecMapExpr<VT,OP,TF> >
3048    : public IsAligned<VT>
3049 {};
3050 /*! \endcond */
3051 //*************************************************************************************************
3052 
3053 
3054 
3055 
3056 //=================================================================================================
3057 //
3058 //  ISPADDED SPECIALIZATIONS
3059 //
3060 //=================================================================================================
3061 
3062 //*************************************************************************************************
3063 /*! \cond BLAZE_INTERNAL */
3064 template< typename VT, typename OP, bool TF >
3065 struct IsPadded< DVecMapExpr<VT,OP,TF> >
3066    : public BoolConstant< IsPadded_v<VT> && IsPaddingEnabled_v<OP> >
3067 {};
3068 /*! \endcond */
3069 //*************************************************************************************************
3070 
3071 } // namespace blaze
3072 
3073 #endif
3074