1 //=================================================================================================
2 /*!
3 //  \file blaze/math/views/Columns.h
4 //  \brief Header file for the implementation of the Columns view
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_VIEWS_COLUMNS_H_
36 #define _BLAZE_MATH_VIEWS_COLUMNS_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <array>
44 #include <utility>
45 #include <vector>
46 #include <blaze/math/Aliases.h>
47 #include <blaze/math/AlignmentFlag.h>
48 #include <blaze/math/constraints/MutableDataAccess.h>
49 #include <blaze/math/constraints/RequiresEvaluation.h>
50 #include <blaze/math/Exception.h>
51 #include <blaze/math/expressions/DeclExpr.h>
52 #include <blaze/math/expressions/MatEvalExpr.h>
53 #include <blaze/math/expressions/MatMapExpr.h>
54 #include <blaze/math/expressions/MatMatAddExpr.h>
55 #include <blaze/math/expressions/MatMatKronExpr.h>
56 #include <blaze/math/expressions/MatMatMapExpr.h>
57 #include <blaze/math/expressions/MatMatMultExpr.h>
58 #include <blaze/math/expressions/MatMatSubExpr.h>
59 #include <blaze/math/expressions/MatNoAliasExpr.h>
60 #include <blaze/math/expressions/MatNoSIMDExpr.h>
61 #include <blaze/math/expressions/MatReduceExpr.h>
62 #include <blaze/math/expressions/MatRepeatExpr.h>
63 #include <blaze/math/expressions/Matrix.h>
64 #include <blaze/math/expressions/MatScalarDivExpr.h>
65 #include <blaze/math/expressions/MatScalarMultExpr.h>
66 #include <blaze/math/expressions/MatSerialExpr.h>
67 #include <blaze/math/expressions/MatTransExpr.h>
68 #include <blaze/math/expressions/SchurExpr.h>
69 #include <blaze/math/expressions/TVecMatMultExpr.h>
70 #include <blaze/math/expressions/VecExpandExpr.h>
71 #include <blaze/math/expressions/VecTVecMapExpr.h>
72 #include <blaze/math/expressions/VecTVecMultExpr.h>
73 #include <blaze/math/InitializerList.h>
74 #include <blaze/math/InversionFlag.h>
75 #include <blaze/math/ReductionFlag.h>
76 #include <blaze/math/RelaxationFlag.h>
77 #include <blaze/math/shims/IsDefault.h>
78 #include <blaze/math/shims/Serial.h>
79 #include <blaze/math/StorageOrder.h>
80 #include <blaze/math/typetraits/HasConstDataAccess.h>
81 #include <blaze/math/typetraits/HasMutableDataAccess.h>
82 #include <blaze/math/typetraits/IsAligned.h>
83 #include <blaze/math/typetraits/IsColumnMajorMatrix.h>
84 #include <blaze/math/typetraits/IsColumns.h>
85 #include <blaze/math/typetraits/IsRestricted.h>
86 #include <blaze/math/typetraits/MaxSize.h>
87 #include <blaze/math/typetraits/Size.h>
88 #include <blaze/math/views/Check.h>
89 #include <blaze/math/views/Forward.h>
90 #include <blaze/math/views/column/ColumnData.h>
91 #include <blaze/math/views/columns/BaseTemplate.h>
92 #include <blaze/math/views/columns/Dense.h>
93 #include <blaze/math/views/columns/Sparse.h>
94 #include <blaze/util/Assert.h>
95 #include <blaze/util/EnableIf.h>
96 #include <blaze/util/FunctionTrace.h>
97 #include <blaze/util/IntegerSequence.h>
98 #include <blaze/util/IntegralConstant.h>
99 #include <blaze/util/MaybeUnused.h>
100 #include <blaze/util/SmallArray.h>
101 #include <blaze/util/Types.h>
102 #include <blaze/util/typetraits/IsPointer.h>
103 #include <blaze/util/typetraits/RemoveReference.h>
104 
105 
106 namespace blaze {
107 
108 //=================================================================================================
109 //
110 //  GLOBAL FUNCTIONS
111 //
112 //=================================================================================================
113 
114 //*************************************************************************************************
115 /*!\brief Creating a view on a selection of columns of the given matrix.
116 // \ingroup columns
117 //
118 // \param matrix The matrix containing the columns.
119 // \param args Optional arguments.
120 // \return View on the specified columns of the matrix.
121 // \exception std::invalid_argument Invalid column access index.
122 //
123 // This function returns an expression representing a selection of columns of the given matrix.
124 
125    \code
126    using blaze::columnMajor;
127 
128    blaze::DynamicMatrix<double,columnMajor> D;
129    blaze::CompressedMatrix<double,columnMajor> S;
130    // ... Resizing and initialization
131 
132    // Creating a view on the 1st and 3rd column of the dense matrix D
133    auto columns1 = columns<1UL,3UL>( D );
134 
135    // Creating a view on the 4th and 2nd column of the sparse matrix S
136    auto columns2 = columns<4UL,2UL>( S );
137    \endcode
138 
139 // By default, the provided column indices are checked at runtime. In case any column is not
140 // properly specified (i.e. if any specified index is greater than or equal to the total number
141 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
142 // can be skipped by providing the optional \a blaze::unchecked argument.
143 
144    \code
145    auto columns1 = columns<1UL,3UL>( D, unchecked );
146    auto columns2 = columns<4UL,2UL>( S, unchecked );
147    \endcode
148 */
149 template< size_t I            // First column index
150         , size_t... Is        // Remaining column indices
151         , typename MT         // Type of the matrix
152         , bool SO             // Storage order
153         , typename... RCAs >  // Optional arguments
decltype(auto)154 inline decltype(auto) columns( Matrix<MT,SO>& matrix, RCAs... args )
155 {
156    BLAZE_FUNCTION_TRACE;
157 
158    using ReturnType = Columns_< MT, index_sequence<I,Is...> >;
159    return ReturnType( *matrix, args... );
160 }
161 //*************************************************************************************************
162 
163 
164 //*************************************************************************************************
165 /*!\brief Creating a view on a selection of columns of the given constant matrix.
166 // \ingroup columns
167 //
168 // \param matrix The constant matrix containing the columns.
169 // \param args Optional arguments.
170 // \return View on the specified columns of the matrix.
171 // \exception std::invalid_argument Invalid column access index.
172 //
173 // This function returns an expression representing a selection of columns of the given constant
174 // matrix.
175 
176    \code
177    using blaze::columnMajor;
178 
179    const blaze::DynamicMatrix<double,columnMajor> D( ... );
180    const blaze::CompressedMatrix<double,columnMajor> S( ... );
181 
182    // Creating a view on the 1st and 3rd column of the dense matrix D
183    auto columns1 = columns<1UL,3UL>( D );
184 
185    // Creating a view on the 4th and 2nd column of the sparse matrix S
186    auto columns2 = columns<4UL,2UL>( S );
187    \endcode
188 
189 // By default, the provided column indices are checked at runtime. In case any column is not
190 // properly specified (i.e. if any specified index is greater than or equal to the total number
191 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
192 // can be skipped by providing the optional \a blaze::unchecked argument.
193 
194    \code
195    auto columns1 = columns<1UL,3UL>( D, unchecked );
196    auto columns2 = columns<4UL,2UL>( S, unchecked );
197    \endcode
198 */
199 template< size_t I            // First column index
200         , size_t... Is        // Remaining column indices
201         , typename MT         // Type of the matrix
202         , bool SO             // Storage order
203         , typename... RCAs >  // Optional arguments
decltype(auto)204 inline decltype(auto) columns( const Matrix<MT,SO>& matrix, RCAs... args )
205 {
206    BLAZE_FUNCTION_TRACE;
207 
208    using ReturnType = const Columns_< const MT, index_sequence<I,Is...> >;
209    return ReturnType( *matrix, args... );
210 }
211 //*************************************************************************************************
212 
213 
214 //*************************************************************************************************
215 /*!\brief Creating a view on a selection of columns of the given temporary matrix.
216 // \ingroup columns
217 //
218 // \param matrix The temporary matrix containing the columns.
219 // \param args Optional arguments.
220 // \return View on the specified columns of the matrix.
221 // \exception std::invalid_argument Invalid column access index.
222 //
223 // This function returns an expression representing a selection of columns of the given temporary
224 // matrix. In case any column is not properly specified (i.e. if any specified index is greater
225 // than or equal to the total number of columns in the given matrix) a \a std::invalid_argument
226 // exception is thrown.
227 */
228 template< size_t I            // First column index
229         , size_t... Is        // Remaining column indices
230         , typename MT         // Type of the matrix
231         , bool SO             // Storage order
232         , typename... RCAs >  // Optional arguments
decltype(auto)233 inline decltype(auto) columns( Matrix<MT,SO>&& matrix, RCAs... args )
234 {
235    BLAZE_FUNCTION_TRACE;
236 
237    using ReturnType = Columns_< MT, index_sequence<I,Is...> >;
238    return ReturnType( *matrix, args... );
239 }
240 //*************************************************************************************************
241 
242 
243 //*************************************************************************************************
244 /*!\brief Creating a view on a selection of columns of the given matrix.
245 // \ingroup columns
246 //
247 // \param matrix The matrix containing the columns.
248 // \param indices Pointer to the first index of the selected columns.
249 // \param n The total number of indices.
250 // \param args Optional arguments.
251 // \return View on the specified columns of the matrix.
252 // \exception std::invalid_argument Invalid column access index.
253 //
254 // This function returns an expression representing a selection of columns of the given matrix.
255 
256    \code
257    using blaze::columnMajor;
258 
259    blaze::DynamicMatrix<double,columnMajor> D;
260    blaze::CompressedMatrix<double,columnMajor> S;
261    // ... Resizing and initialization
262 
263    // Creating a view on the 1st and 3rd column of the dense matrix D
264    const std::vector<size_t> indices1{ 1UL, 3UL };
265    auto columns1 = columns( D, indices1.data(), indices1.size() );
266 
267    // Creating a view on the 4th and 2nd column of the sparse matrix S
268    const std::array<size_t,2UL> indices2{ 4UL, 2UL };
269    auto columns2 = columns( S, indices2.data(), indices2.size() );
270    \endcode
271 
272 // By default, the provided column indices are checked at runtime. In case any column is not
273 // properly specified (i.e. if any specified index is greater than or equal to the total number
274 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
275 // can be skipped by providing the optional \a blaze::unchecked argument.
276 
277    \code
278    auto columns1 = columns( D, indices1.data(), indices1.size(), unchecked );
279    auto columns2 = columns( S, indices2.data(), indices2.size(), unchecked );
280    \endcode
281 */
282 template< typename MT         // Type of the matrix
283         , bool SO             // Storage order
284         , typename T          // Type of the column indices
285         , typename... RCAs >  // Optional arguments
decltype(auto)286 inline decltype(auto) columns( Matrix<MT,SO>& matrix, T* indices, size_t n, RCAs... args )
287 {
288    BLAZE_FUNCTION_TRACE;
289 
290    using ReturnType = Columns_<MT>;
291    return ReturnType( *matrix, indices, n, args... );
292 }
293 //*************************************************************************************************
294 
295 
296 //*************************************************************************************************
297 /*!\brief Creating a view on a selection of columns of the given constant matrix.
298 // \ingroup columns
299 //
300 // \param matrix The constant matrix containing the columns.
301 // \param indices Pointer to the first index of the selected columns.
302 // \param n The total number of indices.
303 // \param args Optional arguments.
304 // \return View on the specified columns of the matrix.
305 // \exception std::invalid_argument Invalid column access index.
306 //
307 // This function returns an expression representing a selection of columns of the given constant
308 // matrix.
309 
310    \code
311    using blaze::columnMajor;
312 
313    blaze::DynamicMatrix<double,columnMajor> D;
314    blaze::CompressedMatrix<double,columnMajor> S;
315    // ... Resizing and initialization
316 
317    // Creating a view on the 1st and 3rd column of the dense matrix D
318    const std::vector<size_t> indices1{ 1UL, 3UL };
319    auto columns1 = columns( D, indices1.data(), indices1.size() );
320 
321    // Creating a view on the 4th and 2nd column of the sparse matrix S
322    const std::array<size_t,2UL> indices2{ 4UL, 2UL };
323    auto columns2 = columns( S, indices2.data(), indices2.size() );
324    \endcode
325 
326 // By default, the provided column indices are checked at runtime. In case any column is not
327 // properly specified (i.e. if any specified index is greater than or equal to the total number
328 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
329 // can be skipped by providing the optional \a blaze::unchecked argument.
330 
331    \code
332    auto columns1 = columns( D, indices1.data(), indices1.size(), unchecked );
333    auto columns2 = columns( S, indices2.data(), indices2.size(), unchecked );
334    \endcode
335 */
336 template< typename MT         // Type of the matrix
337         , bool SO             // Storage order
338         , typename T          // Type of the column indices
339         , typename... RCAs >  // Optional arguments
decltype(auto)340 inline decltype(auto) columns( const Matrix<MT,SO>& matrix, T* indices, size_t n, RCAs... args )
341 {
342    BLAZE_FUNCTION_TRACE;
343 
344    using ReturnType = const Columns_<const MT>;
345    return ReturnType( *matrix, indices, n, args... );
346 }
347 //*************************************************************************************************
348 
349 
350 //*************************************************************************************************
351 /*!\brief Creating a view on a selection of columns of the given temporary matrix.
352 // \ingroup columns
353 //
354 // \param matrix The temporary matrix containing the columns.
355 // \param indices Pointer to the first index of the selected columns.
356 // \param n The total number of indices.
357 // \param args Optional arguments.
358 // \exception std::invalid_argument Invalid column access index.
359 //
360 // This function returns an expression representing a selection of columns of the given temporary
361 // matrix. In case any column is not properly specified (i.e. if any specified index is greater
362 // than or equal to the total number of columns in the given matrix) a \a std::invalid_argument
363 // exception is thrown.
364 */
365 template< typename MT         // Type of the matrix
366         , bool SO             // Storage order
367         , typename T          // Type of the column indices
368         , typename... RCAs >  // Optional arguments
decltype(auto)369 inline decltype(auto) columns( Matrix<MT,SO>&& matrix, T* indices, size_t n, RCAs... args )
370 {
371    BLAZE_FUNCTION_TRACE;
372 
373    using ReturnType = Columns_<MT>;
374    return ReturnType( *matrix, indices, n, args... );
375 }
376 //*************************************************************************************************
377 
378 
379 //*************************************************************************************************
380 /*!\brief Creating a view on a selection of columns of the given matrix.
381 // \ingroup columns
382 //
383 // \param matrix The matrix containing the columns.
384 // \param p Callable producing the indices.
385 // \param n The total number of indices.
386 // \param args Optional arguments.
387 // \return View on the specified columns of the matrix.
388 // \exception std::invalid_argument Invalid column access index.
389 //
390 // This function returns an expression representing a selection of columns of the given matrix.
391 
392    \code
393    using blaze::columnMajor;
394 
395    blaze::DynamicMatrix<double,columnMajor> D;
396    blaze::CompressedMatrix<double,columnMajor> S;
397    // ... Resizing and initialization
398 
399    // Creating a view on the 1st and 3rd column of the dense matrix D
400    auto columns1 = columns( D, []( size_t i ){ return 2UL*i + 1UL; }, 2UL );
401 
402    // Creating a view on the 4th and 2nd column of the sparse matrix S
403    auto columns2 = columns( S, []( size_t i ){ return 4UL - 2UL*i; }, 2UL );
404    \endcode
405 
406 // By default, the provided column indices are checked at runtime. In case any column is not
407 // properly specified (i.e. if any specified index is greater than or equal to the total number
408 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
409 // can be skipped by providing the optional \a blaze::unchecked argument.
410 
411    \code
412    auto columns1 = columns( D, []( size_t i ){ return 2UL*i + 1UL; }, 2UL, unchecked );
413    auto columns2 = columns( S, []( size_t i ){ return 4UL - 2UL*i; }, 2UL, unchecked );
414    \endcode
415 */
416 template< typename MT         // Type of the matrix
417         , bool SO             // Storage order
418         , typename P          // Type of the index producer
419         , typename... RCAs >  // Optional arguments
decltype(auto)420 inline decltype(auto) columns( Matrix<MT,SO>& matrix, P p, size_t n, RCAs... args )
421 {
422    BLAZE_FUNCTION_TRACE;
423 
424    using ReturnType = Columns_<MT,P>;
425    return ReturnType( *matrix, p, n, args... );
426 }
427 //*************************************************************************************************
428 
429 
430 //*************************************************************************************************
431 /*!\brief Creating a view on a selection of columns of the given constant matrix.
432 // \ingroup columns
433 //
434 // \param matrix The constant matrix containing the columns.
435 // \param p Callable producing the indices.
436 // \param n The total number of indices.
437 // \param args Optional arguments.
438 // \return View on the specified columns of the matrix.
439 // \exception std::invalid_argument Invalid column access index.
440 //
441 // This function returns an expression representing a selection of columns of the given constant
442 // matrix.
443 
444    \code
445    using blaze::columnMajor;
446 
447    blaze::DynamicMatrix<double,columnMajor> D;
448    blaze::CompressedMatrix<double,columnMajor> S;
449    // ... Resizing and initialization
450 
451    // Creating a view on the 1st and 3rd column of the dense matrix D
452    auto columns1 = columns( D, []( size_t i ){ return 2UL*i + 1UL; }, 2UL );
453 
454    // Creating a view on the 4th and 2nd column of the sparse matrix S
455    const std::array<size_t,2UL> indices2{ 4UL, 2UL };
456    auto columns2 = columns( S, []( size_t i ){ return 4UL - 2UL*i; }, 2UL );
457    \endcode
458 
459 // By default, the provided column indices are checked at runtime. In case any column is not
460 // properly specified (i.e. if any specified index is greater than or equal to the total number
461 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
462 // can be skipped by providing the optional \a blaze::unchecked argument.
463 
464    \code
465    auto columns1 = columns( D, []( size_t i ){ return 2UL*i + 1UL; }, 2UL, unchecked );
466    auto columns2 = columns( S, []( size_t i ){ return 4UL - 2UL*i; }, 2UL, unchecked );
467    \endcode
468 */
469 template< typename MT         // Type of the matrix
470         , bool SO             // Storage order
471         , typename P          // Type of the index producer
472         , typename... RCAs >  // Optional arguments
decltype(auto)473 inline decltype(auto) columns( const Matrix<MT,SO>& matrix, P p, size_t n, RCAs... args )
474 {
475    BLAZE_FUNCTION_TRACE;
476 
477    using ReturnType = const Columns_<const MT,P>;
478    return ReturnType( *matrix, p, n, args... );
479 }
480 //*************************************************************************************************
481 
482 
483 //*************************************************************************************************
484 /*!\brief Creating a view on a selection of columns of the given temporary matrix.
485 // \ingroup columns
486 //
487 // \param matrix The temporary matrix containing the columns.
488 // \param p Callable producing the indices.
489 // \param n The total number of indices.
490 // \param args Optional arguments.
491 // \exception std::invalid_argument Invalid column access index.
492 //
493 // This function returns an expression representing a selection of columns of the given temporary
494 // matrix. In case any column is not properly specified (i.e. if any specified index is greater
495 // than or equal to the total number of columns in the given matrix) a \a std::invalid_argument
496 // exception is thrown.
497 */
498 template< typename MT         // Type of the matrix
499         , bool SO             // Storage order
500         , typename P          // Type of the index producer
501         , typename... RCAs >  // Optional arguments
decltype(auto)502 inline decltype(auto) columns( Matrix<MT,SO>&& matrix, P p, size_t n, RCAs... args )
503 {
504    BLAZE_FUNCTION_TRACE;
505 
506    using ReturnType = Columns_<MT,P>;
507    return ReturnType( *matrix, p, n, args... );
508 }
509 //*************************************************************************************************
510 
511 
512 //*************************************************************************************************
513 /*!\brief Creating a view on a selection of columns of the given matrix.
514 // \ingroup columns
515 //
516 // \param matrix The matrix containing the columns.
517 // \param indices The sequence of column indices.
518 // \param args Optional arguments.
519 // \return View on the specified columns of the matrix.
520 // \exception std::invalid_argument Invalid column access index.
521 //
522 // This function returns an expression representing a selection of columns of the given matrix.
523 
524    \code
525    using blaze::columnMajor;
526    using blaze::index_sequence;
527 
528    blaze::DynamicMatrix<double,columnMajor> D;
529    blaze::CompressedMatrix<double,columnMajor> S;
530    // ... Resizing and initialization
531 
532    // Creating a view on the 1st and 3rd column of the dense matrix D
533    auto columns1 = columns( D, index_sequence<1UL,3UL>() );
534 
535    // Creating a view on the 4th and 2nd column of the sparse matrix S
536    auto columns2 = columns( S, index_sequence<4UL,2UL>() );
537    \endcode
538 
539 // By default, the provided column indices are checked at runtime. In case any column is not
540 // properly specified (i.e. if any specified index is greater than or equal to the total number
541 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
542 // can be skipped by providing the optional \a blaze::unchecked argument.
543 
544    \code
545    auto columns1 = columns( D, index_sequence<1UL,3UL>(), unchecked );
546    auto columns2 = columns( S, index_sequence<4UL,2UL>(), unchecked );
547    \endcode
548 */
549 template< typename MT         // Type of the matrix
550         , size_t... Is        // Column indices
551         , typename... RCAs >  // Optional arguments
decltype(auto)552 inline decltype(auto) columns( MT&& matrix, index_sequence<Is...> indices, RCAs... args )
553 {
554    BLAZE_FUNCTION_TRACE;
555 
556    MAYBE_UNUSED( indices );
557 
558    return columns<Is...>( std::forward<MT>( matrix ), args... );
559 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
564 /*!\brief Creating a view on a selection of columns of the given matrix.
565 // \ingroup columns
566 //
567 // \param matrix The matrix containing the columns.
568 // \param indices The list of column indices.
569 // \param args Optional arguments.
570 // \return View on the specified columns of the matrix.
571 // \exception std::invalid_argument Invalid column access index.
572 //
573 // This function returns an expression representing a selection of columns of the given matrix.
574 
575    \code
576    using blaze::columnMajor;
577 
578    blaze::DynamicMatrix<double,columnMajor> D;
579    blaze::CompressedMatrix<double,columnMajor> S;
580    // ... Resizing and initialization
581 
582    // Creating a view on the 1st and 3rd column of the dense matrix D
583    auto columns1 = columns( D, { 1UL, 3UL } );
584 
585    // Creating a view on the 4th and 2nd column of the sparse matrix S
586    auto columns2 = columns( S, { 4UL, 2UL } );
587    \endcode
588 
589 // By default, the provided column indices are checked at runtime. In case any column is not
590 // properly specified (i.e. if any specified index is greater than or equal to the total number
591 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
592 // can be skipped by providing the optional \a blaze::unchecked argument.
593 
594    \code
595    auto columns1 = columns( D, { 1UL, 3UL }, unchecked );
596    auto columns2 = columns( S, { 4UL, 2UL }, unchecked );
597    \endcode
598 */
599 template< typename MT         // Type of the matrix
600         , typename T          // Type of the column indices
601         , typename... RCAs >  // Optional arguments
decltype(auto)602 inline decltype(auto) columns( MT&& matrix, initializer_list<T> indices, RCAs... args )
603 {
604    BLAZE_FUNCTION_TRACE;
605 
606    return columns( std::forward<MT>( matrix ), indices.begin(), indices.size(), args... );
607 }
608 //*************************************************************************************************
609 
610 
611 //*************************************************************************************************
612 /*!\brief Creating a view on a selection of columns of the given matrix.
613 // \ingroup columns
614 //
615 // \param matrix The matrix containing the columns.
616 // \param indices The array of column indices.
617 // \param args Optional arguments.
618 // \return View on the specified columns of the matrix.
619 // \exception std::invalid_argument Invalid column access index.
620 //
621 // This function returns an expression representing a selection of columns of the given matrix.
622 
623    \code
624    using blaze::columnMajor;
625 
626    blaze::DynamicMatrix<double,columnMajor> D;
627    blaze::CompressedMatrix<double,columnMajor> S;
628    // ... Resizing and initialization
629 
630    // Creating a view on the 1st and 3rd column of the dense matrix D
631    const std::array<size_t,2UL> indices1{ 1UL, 3UL };
632    auto columns1 = columns( D, indices1 );
633 
634    // Creating a view on the 4th and 2nd column of the sparse matrix S
635    const std::array<size_t,2UL> indices2{ 4UL, 2UL };
636    auto columns2 = columns( S, indices2 );
637    \endcode
638 
639 // By default, the provided column indices are checked at runtime. In case any column is not
640 // properly specified (i.e. if any specified index is greater than or equal to the total number
641 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
642 // can be skipped by providing the optional \a blaze::unchecked argument.
643 
644    \code
645    auto columns1 = columns( D, indices1, unchecked );
646    auto columns2 = columns( S, indices2, unchecked );
647    \endcode
648 */
649 template< typename MT         // Type of the matrix
650         , typename T          // Type of the column indices
651         , size_t N            // Number of indices
652         , typename... RCAs >  // Optional arguments
decltype(auto)653 inline decltype(auto) columns( MT&& matrix, const std::array<T,N>& indices, RCAs... args )
654 {
655    BLAZE_FUNCTION_TRACE;
656 
657    return columns( std::forward<MT>( matrix ), indices.data(), N, args... );
658 }
659 //*************************************************************************************************
660 
661 
662 //*************************************************************************************************
663 /*!\brief Creating a view on a selection of columns of the given matrix.
664 // \ingroup columns
665 //
666 // \param matrix The matrix containing the columns.
667 // \param indices The vector of column indices.
668 // \param args Optional arguments.
669 // \return View on the specified columns of the matrix.
670 // \exception std::invalid_argument Invalid column access index.
671 //
672 // This function returns an expression representing a selection of columns of the given matrix.
673 
674    \code
675    using blaze::columnMajor;
676 
677    blaze::DynamicMatrix<double,columnMajor> D;
678    blaze::CompressedMatrix<double,columnMajor> S;
679    // ... Resizing and initialization
680 
681    // Creating a view on the 1st and 3rd column of the dense matrix D
682    const std::vector<size_t> indices1{ 1UL, 3UL };
683    auto columns1 = columns( D, indices1 );
684 
685    // Creating a view on the 4th and 2nd column of the sparse matrix S
686    const std::vector<size_t> indices2{ 4UL, 2UL };
687    auto columns2 = columns( S, indices2 );
688    \endcode
689 
690 // By default, the provided column indices are checked at runtime. In case any column is not
691 // properly specified (i.e. if any specified index is greater than or equal to the total number
692 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
693 // can be skipped by providing the optional \a blaze::unchecked argument.
694 
695    \code
696    auto columns1 = columns( D, indices1, unchecked );
697    auto columns2 = columns( S, indices2, unchecked );
698    \endcode
699 */
700 template< typename MT         // Type of the matrix
701         , typename T          // Type of the column indices
702         , typename... RCAs >  // Optional arguments
decltype(auto)703 inline decltype(auto) columns( MT&& matrix, const std::vector<T>& indices, RCAs... args )
704 {
705    BLAZE_FUNCTION_TRACE;
706 
707    return columns( std::forward<MT>( matrix ), indices.data(), indices.size(), args... );
708 }
709 //*************************************************************************************************
710 
711 
712 //*************************************************************************************************
713 /*! \cond BLAZE_INTERNAL */
714 /*!\brief Creating a view on a selection of columns of the given matrix.
715 // \ingroup columns
716 //
717 // \param matrix The matrix containing the columns.
718 // \param indices The vector of column indices.
719 // \param args Optional arguments.
720 // \return View on the specified columns of the matrix.
721 // \exception std::invalid_argument Invalid column access index.
722 //
723 // This function returns an expression representing a selection of columns of the given matrix.
724 
725    \code
726    using blaze::columnMajor;
727 
728    blaze::DynamicMatrix<double,columnMajor> D;
729    blaze::CompressedMatrix<double,columnMajor> S;
730    // ... Resizing and initialization
731 
732    // Creating a view on the 1st and 3rd column of the dense matrix D
733    blaze::SmallArray<size_t,2UL> indices1{ 1UL, 3UL };
734    auto columns1 = columns( D, indices1 );
735 
736    // Creating a view on the 4th and 2nd column of the sparse matrix S
737    blaze::SmallArray<size_t,2UL> indices2{ 4UL, 2UL };
738    auto columns2 = columns( S, indices2 );
739    \endcode
740 
741 // By default, the provided column indices are checked at runtime. In case any column is not
742 // properly specified (i.e. if any specified index is greater than or equal to the total number
743 // of columns in the given matrix) a \a std::invalid_argument exception is thrown. The checks
744 // can be skipped by providing the optional \a blaze::unchecked argument.
745 
746    \code
747    auto columns1 = columns( D, indices1, unchecked );
748    auto columns2 = columns( S, indices2, unchecked );
749    \endcode
750 */
751 template< typename MT         // Type of the matrix
752         , typename T          // Type of the column indices
753         , size_t N            // Number of preallocated elements
754         , typename... RCAs >  // Optional arguments
decltype(auto)755 inline decltype(auto) columns( MT&& matrix, const SmallArray<T,N>& indices, RCAs... args )
756 {
757    BLAZE_FUNCTION_TRACE;
758 
759    return columns( std::forward<MT>( matrix ), indices.data(), indices.size(), args... );
760 }
761 /*! \endcond */
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
766 /*! \cond BLAZE_INTERNAL */
767 /*!\brief Creating a view on a selection of columns of the given matrix.
768 // \ingroup columns
769 //
770 // \param matrix The matrix containing the columns.
771 // \param pair The pair of arguments for the element selection.
772 // \param args Optional arguments.
773 // \return View on the specified columns of the matrix.
774 // \exception std::invalid_argument Invalid column access index.
775 //
776 // This function returns an expression representing a selection of columns of the given matrix.
777 // In case any column is not properly specified (i.e. if any specified index is greater than or
778 // equal to the total number of columns in the given matrix) a \a std::invalid_argument exception
779 // is thrown.
780 */
781 template< typename MT         // Type of the matrix
782         , typename T1         // First type of the pair of arguments
783         , typename T2         // Second type of the pair of arguments
784         , typename... RRAs >  // Optional arguments
decltype(auto)785 inline decltype(auto) columns( MT&& matrix, const std::pair<T1,T2>& pair, RRAs... args )
786 {
787    BLAZE_FUNCTION_TRACE;
788 
789    return columns( std::forward<MT>( matrix ), pair.first, pair.second, args... );
790 }
791 /*! \endcond */
792 //*************************************************************************************************
793 
794 
795 
796 
797 //=================================================================================================
798 //
799 //  GLOBAL RESTRUCTURING FUNCTIONS
800 //
801 //=================================================================================================
802 
803 //*************************************************************************************************
804 /*! \cond BLAZE_INTERNAL */
805 /*!\brief Creating a view on a selection of columns on the given matrix/matrix addition.
806 // \ingroup columns
807 //
808 // \param matrix The constant matrix/matrix addition.
809 // \param args The runtime column arguments.
810 // \return View on the specified selection of columns on the addition.
811 // \exception std::invalid_argument Invalid column access index.
812 //
813 // This function returns an expression representing the specified selection of columns on the
814 // given matrix/matrix addition.
815 */
816 template< size_t... CCAs    // Compile time column arguments
817         , typename MT       // Matrix base type of the expression
818         , typename... RCAs  // Runtime column arguments
819         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)820 inline decltype(auto) columns( const MatMatAddExpr<MT>& matrix, RCAs... args )
821 {
822    BLAZE_FUNCTION_TRACE;
823 
824    return columns<CCAs...>( (*matrix).leftOperand(), args... ) +
825           columns<CCAs...>( (*matrix).rightOperand(), args... );
826 }
827 /*! \endcond */
828 //*************************************************************************************************
829 
830 
831 //*************************************************************************************************
832 /*! \cond BLAZE_INTERNAL */
833 /*!\brief Creating a view on a selection of columns on the given matrix/matrix subtraction.
834 // \ingroup columns
835 //
836 // \param matrix The constant matrix/matrix subtraction.
837 // \param args The runtime column arguments.
838 // \return View on the specified selection of columns on the subtraction.
839 // \exception std::invalid_argument Invalid column access index.
840 //
841 // This function returns an expression representing the specified selection of columns on the
842 // given matrix/matrix subtraction.
843 */
844 template< size_t... CCAs    // Compile time column arguments
845         , typename MT       // Matrix base type of the expression
846         , typename... RCAs  // Runtime column arguments
847         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)848 inline decltype(auto) columns( const MatMatSubExpr<MT>& matrix, RCAs... args )
849 {
850    BLAZE_FUNCTION_TRACE;
851 
852    return columns<CCAs...>( (*matrix).leftOperand(), args... ) -
853           columns<CCAs...>( (*matrix).rightOperand(), args... );
854 }
855 /*! \endcond */
856 //*************************************************************************************************
857 
858 
859 //*************************************************************************************************
860 /*! \cond BLAZE_INTERNAL */
861 /*!\brief Creating a view on a selection of columns on the given Schur product.
862 // \ingroup columns
863 //
864 // \param matrix The constant Schur product.
865 // \param args The runtime column arguments.
866 // \return View on the specified selection of columns on the Schur product.
867 // \exception std::invalid_argument Invalid column access index.
868 //
869 // This function returns an expression representing the specified selection of columns on the
870 // given Schur product.
871 */
872 template< size_t... CCAs    // Compile time column arguments
873         , typename MT       // Matrix base type of the expression
874         , typename... RCAs  // Runtime column arguments
875         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)876 inline decltype(auto) columns( const SchurExpr<MT>& matrix, RCAs... args )
877 {
878    BLAZE_FUNCTION_TRACE;
879 
880    return columns<CCAs...>( (*matrix).leftOperand(), args... ) %
881           columns<CCAs...>( (*matrix).rightOperand(), args... );
882 }
883 /*! \endcond */
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
888 /*! \cond BLAZE_INTERNAL */
889 /*!\brief Creating a view on a selection of columns on the given matrix/matrix multiplication.
890 // \ingroup columns
891 //
892 // \param matrix The constant matrix/matrix multiplication.
893 // \param args The runtime column arguments.
894 // \return View on the specified selection of columns on the multiplication.
895 // \exception std::invalid_argument Invalid column access index.
896 //
897 // This function returns an expression representing the specified selection of columns on the
898 // given matrix/matrix multiplication.
899 */
900 template< size_t... CCAs    // Compile time column arguments
901         , typename MT       // Matrix base type of the expression
902         , typename... RCAs  // Runtime column arguments
903         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)904 inline decltype(auto) columns( const MatMatMultExpr<MT>& matrix, RCAs... args )
905 {
906    BLAZE_FUNCTION_TRACE;
907 
908    return (*matrix).leftOperand() * columns<CCAs...>( (*matrix).rightOperand(), args... );
909 }
910 /*! \endcond */
911 //*************************************************************************************************
912 
913 
914 //*************************************************************************************************
915 /*! \cond BLAZE_INTERNAL */
916 /*!\brief Creating a view on a selection of columns on the given Kronecker product.
917 // \ingroup columns
918 //
919 // \param matrix The constant Kronecker product.
920 // \param args Optional arguments.
921 // \return View on the specified selection of columns on the Kronecker product.
922 // \exception std::invalid_argument Invalid column access index.
923 //
924 // This function returns an expression representing the specified selection of columns on the
925 // given Kronecker product.
926 */
927 template< size_t I            // First column index
928         , size_t... Is        // Remaining column indices
929         , typename MT         // Matrix base type of the expression
930         , typename... RCAs >  // Optional arguments
decltype(auto)931 inline decltype(auto) columns( const MatMatKronExpr<MT>& matrix, RCAs... args )
932 {
933    BLAZE_FUNCTION_TRACE;
934 
935    decltype(auto) lhs( (*matrix).leftOperand()  );
936    decltype(auto) rhs( (*matrix).rightOperand() );
937 
938    const size_t M( rhs.rows()    );
939    const size_t N( rhs.columns() );
940 
941    const auto lhsRows( [M]( size_t i ){ return i / M; } );
942    const auto rhsRows( [M]( size_t i ){ return i % M; } );
943 
944    const auto lhsColumns( [N]( size_t i ) {
945       constexpr size_t indices[] = { I, Is... };
946       return indices[i] / N;
947    } );
948 
949    const auto rhsColumns( [N]( size_t i ) {
950       constexpr size_t indices[] = { I, Is... };
951       return indices[i] % N;
952    } );
953 
954    return columns( rows( lhs, lhsRows, (*matrix).rows(), args... ), lhsColumns, sizeof...(Is)+1UL, args... ) %
955           columns( rows( rhs, rhsRows, (*matrix).rows(), args... ), rhsColumns, sizeof...(Is)+1UL, args... );
956 }
957 /*! \endcond */
958 //*************************************************************************************************
959 
960 
961 //*************************************************************************************************
962 /*! \cond BLAZE_INTERNAL */
963 /*!\brief Creating a view on a selection of columns on the given Kronecker product.
964 // \ingroup columns
965 //
966 // \param matrix The constant Kronecker product.
967 // \param indices Pointer to the first index of the selected columns.
968 // \param n The total number of indices.
969 // \param args Optional arguments.
970 // \return View on the specified selection of columns on the Kronecker product.
971 // \exception std::invalid_argument Invalid column access index.
972 //
973 // This function returns an expression representing the specified selection of columns on the
974 // given Kronecker product.
975 */
976 template< typename MT         // Matrix base type of the expression
977         , typename T          // Type of the column indices
978         , typename... RCAs >  // Optional arguments
decltype(auto)979 inline decltype(auto) columns( const MatMatKronExpr<MT>& matrix, T* indices, size_t n, RCAs... args )
980 {
981    BLAZE_FUNCTION_TRACE;
982 
983    decltype(auto) lhs( (*matrix).leftOperand()  );
984    decltype(auto) rhs( (*matrix).rightOperand() );
985 
986    const size_t M( rhs.rows()    );
987    const size_t N( rhs.columns() );
988 
989    const auto lhsRows( [M]( size_t i ){ return i / M; } );
990    const auto rhsRows( [M]( size_t i ){ return i % M; } );
991 
992    SmallArray<size_t,128UL> lhsColumns;
993    lhsColumns.reserve( n );
994 
995    for( size_t i=0UL; i<n; ++i ) {
996       lhsColumns.pushBack( indices[i] / N );
997    }
998 
999    SmallArray<size_t,128UL> rhsColumns;
1000    rhsColumns.reserve( n );
1001 
1002    for( size_t i=0UL; i<n; ++i ) {
1003       rhsColumns.pushBack( indices[i] % N );
1004    }
1005 
1006    return columns( rows( lhs, lhsRows, (*matrix).rows(), args... ), lhsColumns, n, args... ) %
1007           columns( rows( rhs, rhsRows, (*matrix).rows(), args... ), rhsColumns, n, args... );
1008 }
1009 /*! \endcond */
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1014 /*! \cond BLAZE_INTERNAL */
1015 /*!\brief Creating a view on a selection of columns on the given Kronecker product.
1016 // \ingroup columns
1017 //
1018 // \param matrix The constant Kronecker product.
1019 // \param p Callable producing the indices.
1020 // \param n The total number of indices.
1021 // \param args Optional arguments.
1022 // \return View on the specified selection of columns on the Kronecker product.
1023 // \exception std::invalid_argument Invalid column access index.
1024 //
1025 // This function returns an expression representing the specified selection of columns on the
1026 // given Kronecker product.
1027 */
1028 template< typename MT         // Matrix base type of the expression
1029         , typename P          // Type of the index producer
1030         , typename... RCAs >  // Optional arguments
decltype(auto)1031 inline decltype(auto) columns( const MatMatKronExpr<MT>& matrix, P p, size_t n, RCAs... args )
1032 {
1033    BLAZE_FUNCTION_TRACE;
1034 
1035    decltype(auto) lhs( (*matrix).leftOperand()  );
1036    decltype(auto) rhs( (*matrix).rightOperand() );
1037 
1038    const size_t M( rhs.rows()    );
1039    const size_t N( rhs.columns() );
1040 
1041    const auto lhsRows( [M]( size_t i ){ return i / M; } );
1042    const auto rhsRows( [M]( size_t i ){ return i % M; } );
1043 
1044    const auto lhsColumns( [p,N]( size_t i ) { return p(i) / N; } );
1045    const auto rhsColumns( [p,N]( size_t i ) { return p(i) % N; } );
1046 
1047    return columns( rows( lhs, lhsRows, (*matrix).rows(), args... ), lhsColumns, n, args... ) %
1048           columns( rows( rhs, rhsRows, (*matrix).rows(), args... ), rhsColumns, n, args... );
1049 }
1050 /*! \endcond */
1051 //*************************************************************************************************
1052 
1053 
1054 //*************************************************************************************************
1055 /*! \cond BLAZE_INTERNAL */
1056 /*!\brief Creating a view on a selection of columns on the given outer product.
1057 // \ingroup columns
1058 //
1059 // \param matrix The constant outer product.
1060 // \param args The runtime column arguments.
1061 // \return View on the specified selection of columns on the outer product.
1062 // \exception std::invalid_argument Invalid column access index.
1063 //
1064 // This function returns an expression representing the specified selection of columns on the
1065 // given outer product.
1066 */
1067 template< size_t... CCAs    // Compile time column arguments
1068         , typename MT       // Matrix base type of the expression
1069         , typename... RCAs  // Runtime column arguments
1070         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1071 inline decltype(auto) columns( const VecTVecMultExpr<MT>& matrix, RCAs... args )
1072 {
1073    BLAZE_FUNCTION_TRACE;
1074 
1075    try {
1076       return (*matrix).leftOperand() * elements<CCAs...>( (*matrix).rightOperand(), args... );
1077    }
1078    catch( ... ) {
1079       BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1080    }
1081 }
1082 /*! \endcond */
1083 //*************************************************************************************************
1084 
1085 
1086 //*************************************************************************************************
1087 /*! \cond BLAZE_INTERNAL */
1088 /*!\brief Creating a view on a selection of columns on the given matrix/scalar multiplication.
1089 // \ingroup columns
1090 //
1091 // \param matrix The constant matrix/scalar multiplication.
1092 // \param args The runtime column arguments.
1093 // \return View on the specified selection of columns on the multiplication.
1094 // \exception std::invalid_argument Invalid column access index.
1095 //
1096 // This function returns an expression representing the specified selection of columns on the
1097 // given matrix/scalar multiplication.
1098 */
1099 template< size_t... CCAs    // Compile time column arguments
1100         , typename MT       // Matrix base type of the expression
1101         , typename... RCAs  // Runtime column arguments
1102         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1103 inline decltype(auto) columns( const MatScalarMultExpr<MT>& matrix, RCAs... args )
1104 {
1105    BLAZE_FUNCTION_TRACE;
1106 
1107    return columns<CCAs...>( (*matrix).leftOperand(), args... ) * (*matrix).rightOperand();
1108 }
1109 /*! \endcond */
1110 //*************************************************************************************************
1111 
1112 
1113 //*************************************************************************************************
1114 /*! \cond BLAZE_INTERNAL */
1115 /*!\brief Creating a view on a selection of columns on the given matrix/scalar division.
1116 // \ingroup columns
1117 //
1118 // \param matrix The constant matrix/scalar division.
1119 // \param args The runtime column arguments.
1120 // \return View on the specified selection of columns on the division.
1121 // \exception std::invalid_argument Invalid column access index.
1122 //
1123 // This function returns an expression representing the specified selection of columns on the
1124 // given matrix/scalar division.
1125 */
1126 template< size_t... CCAs    // Compile time column arguments
1127         , typename MT       // Matrix base type of the expression
1128         , typename... RCAs  // Runtime column arguments
1129         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1130 inline decltype(auto) columns( const MatScalarDivExpr<MT>& matrix, RCAs... args )
1131 {
1132    BLAZE_FUNCTION_TRACE;
1133 
1134    return columns<CCAs...>( (*matrix).leftOperand(), args... ) / (*matrix).rightOperand();
1135 }
1136 /*! \endcond */
1137 //*************************************************************************************************
1138 
1139 
1140 //*************************************************************************************************
1141 /*! \cond BLAZE_INTERNAL */
1142 /*!\brief Creating a view on a selection of columns on the given unary matrix map operation.
1143 // \ingroup columns
1144 //
1145 // \param matrix The constant unary matrix map operation.
1146 // \param args The runtime column arguments.
1147 // \return View on the specified selection of columns on the unary map operation.
1148 // \exception std::invalid_argument Invalid column access index.
1149 //
1150 // This function returns an expression representing the specified selection of columns on the
1151 // given unary matrix map operation.
1152 */
1153 template< size_t... CCAs    // Compile time column arguments
1154         , typename MT       // Matrix base type of the expression
1155         , typename... RCAs  // Runtime column arguments
1156         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1157 inline decltype(auto) columns( const MatMapExpr<MT>& matrix, RCAs... args )
1158 {
1159    BLAZE_FUNCTION_TRACE;
1160 
1161    return map( columns<CCAs...>( (*matrix).operand(), args... ), (*matrix).operation() );
1162 }
1163 /*! \endcond */
1164 //*************************************************************************************************
1165 
1166 
1167 //*************************************************************************************************
1168 /*! \cond BLAZE_INTERNAL */
1169 /*!\brief Creating a view on a selection of columns on the given binary matrix map operation.
1170 // \ingroup columns
1171 //
1172 // \param matrix The constant binary matrix map operation.
1173 // \param args The runtime column arguments.
1174 // \return View on the specified selection of columns on the binary map operation.
1175 // \exception std::invalid_argument Invalid column access index.
1176 //
1177 // This function returns an expression representing the specified selection of columns on the
1178 // given binary matrix map operation.
1179 */
1180 template< size_t... CCAs    // Compile time column arguments
1181         , typename MT       // Matrix base type of the expression
1182         , typename... RCAs  // Runtime column arguments
1183         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1184 inline decltype(auto) columns( const MatMatMapExpr<MT>& matrix, RCAs... args )
1185 {
1186    BLAZE_FUNCTION_TRACE;
1187 
1188    return map( columns<CCAs...>( (*matrix).leftOperand(), args... ),
1189                columns<CCAs...>( (*matrix).rightOperand(), args... ),
1190                (*matrix).operation() );
1191 }
1192 /*! \endcond */
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1197 /*! \cond BLAZE_INTERNAL */
1198 /*!\brief Creating a view on a selection of columns on the given outer map operation.
1199 // \ingroup columns
1200 //
1201 // \param matrix The constant outer map operation.
1202 // \param args The runtime column arguments.
1203 // \return View on the specified selection of columns on the outer map operation.
1204 // \exception std::invalid_argument Invalid column access index.
1205 //
1206 // This function returns an expression representing the specified selection of columns on the
1207 // given outer map operation.
1208 */
1209 template< size_t... CCAs    // Compile time column arguments
1210         , typename MT       // Matrix base type of the expression
1211         , typename... RCAs  // Runtime column arguments
1212         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1213 inline decltype(auto) columns( const VecTVecMapExpr<MT>& matrix, RCAs... args )
1214 {
1215    BLAZE_FUNCTION_TRACE;
1216 
1217    try {
1218       return map( (*matrix).leftOperand(),
1219                   elements<CCAs...>( (*matrix).rightOperand(), args... ), (*matrix).operation() );
1220    }
1221    catch( ... ) {
1222       BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1223    }
1224 }
1225 /*! \endcond */
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1230 /*! \cond BLAZE_INTERNAL */
1231 /*!\brief Creating a view on a selection of columns on the given matrix evaluation operation.
1232 // \ingroup columns
1233 //
1234 // \param matrix The constant matrix evaluation operation.
1235 // \param args The runtime column arguments.
1236 // \return View on the specified selection of columns on the evaluation operation.
1237 // \exception std::invalid_argument Invalid column access index.
1238 //
1239 // This function returns an expression representing the specified selection of columns on the
1240 // given matrix evaluation operation.
1241 */
1242 template< size_t... CCAs    // Compile time column arguments
1243         , typename MT       // Matrix base type of the expression
1244         , typename... RCAs  // Runtime column arguments
1245         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1246 inline decltype(auto) columns( const MatEvalExpr<MT>& matrix, RCAs... args )
1247 {
1248    BLAZE_FUNCTION_TRACE;
1249 
1250    return eval( columns<CCAs...>( (*matrix).operand(), args... ) );
1251 }
1252 /*! \endcond */
1253 //*************************************************************************************************
1254 
1255 
1256 //*************************************************************************************************
1257 /*! \cond BLAZE_INTERNAL */
1258 /*!\brief Creating a view on a selection of columns on the given matrix serialization operation.
1259 // \ingroup columns
1260 //
1261 // \param matrix The constant matrix serialization operation.
1262 // \param args The runtime column arguments.
1263 // \return View on the specified selection of columns on the serialization operation.
1264 // \exception std::invalid_argument Invalid column access index.
1265 //
1266 // This function returns an expression representing the specified selection of columns on the
1267 // given matrix serialization operation.
1268 */
1269 template< size_t... CCAs    // Compile time column arguments
1270         , typename MT       // Matrix base type of the expression
1271         , typename... RCAs  // Runtime column arguments
1272         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1273 inline decltype(auto) columns( const MatSerialExpr<MT>& matrix, RCAs... args )
1274 {
1275    BLAZE_FUNCTION_TRACE;
1276 
1277    return serial( columns<CCAs...>( (*matrix).operand(), args... ) );
1278 }
1279 /*! \endcond */
1280 //*************************************************************************************************
1281 
1282 
1283 //*************************************************************************************************
1284 /*! \cond BLAZE_INTERNAL */
1285 /*!\brief Creating a view on a selection of columns on the given matrix no-alias operation.
1286 // \ingroup columns
1287 //
1288 // \param matrix The constant matrix no-alias operation.
1289 // \param args The runtime column arguments.
1290 // \return View on the specified selection of columns on the no-alias operation.
1291 // \exception std::invalid_argument Invalid column access index.
1292 //
1293 // This function returns an expression representing the specified selection of columns on the
1294 // given matrix no-alias operation.
1295 */
1296 template< size_t... CCAs    // Compile time column arguments
1297         , typename MT       // Matrix base type of the expression
1298         , typename... RCAs  // Runtime column arguments
1299         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1300 inline decltype(auto) columns( const MatNoAliasExpr<MT>& matrix, RCAs... args )
1301 {
1302    BLAZE_FUNCTION_TRACE;
1303 
1304    return noalias( columns<CCAs...>( (*matrix).operand(), args... ) );
1305 }
1306 /*! \endcond */
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1311 /*! \cond BLAZE_INTERNAL */
1312 /*!\brief Creating a view on a selection of columns on the given matrix no-SIMD operation.
1313 // \ingroup columns
1314 //
1315 // \param matrix The constant matrix no-SIMD operation.
1316 // \param args The runtime column arguments.
1317 // \return View on the specified selection of columns on the no-SIMD operation.
1318 // \exception std::invalid_argument Invalid column access index.
1319 //
1320 // This function returns an expression representing the specified selection of columns on the
1321 // given matrix no-SIMD operation.
1322 */
1323 template< size_t... CCAs    // Compile time column arguments
1324         , typename MT       // Matrix base type of the expression
1325         , typename... RCAs  // Runtime column arguments
1326         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1327 inline decltype(auto) columns( const MatNoSIMDExpr<MT>& matrix, RCAs... args )
1328 {
1329    BLAZE_FUNCTION_TRACE;
1330 
1331    return nosimd( columns<CCAs...>( (*matrix).operand(), args... ) );
1332 }
1333 /*! \endcond */
1334 //*************************************************************************************************
1335 
1336 
1337 //*************************************************************************************************
1338 /*! \cond BLAZE_INTERNAL */
1339 /*!\brief Creating a view on a selection of columns on the given matrix declaration operation.
1340 // \ingroup columns
1341 //
1342 // \param matrix The constant matrix declaration operation.
1343 // \param args The runtime column arguments.
1344 // \return View on the specified selection of columns on the declaration operation.
1345 // \exception std::invalid_argument Invalid column access index.
1346 //
1347 // This function returns an expression representing the specified selection of columns on the
1348 // given matrix declaration operation.
1349 */
1350 template< size_t... CCAs    // Compile time column arguments
1351         , typename MT       // Matrix base type of the expression
1352         , typename... RCAs  // Runtime column arguments
1353         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1354 inline decltype(auto) columns( const DeclExpr<MT>& matrix, RCAs... args )
1355 {
1356    BLAZE_FUNCTION_TRACE;
1357 
1358    return columns<CCAs...>( (*matrix).operand(), args... );
1359 }
1360 /*! \endcond */
1361 //*************************************************************************************************
1362 
1363 
1364 //*************************************************************************************************
1365 /*! \cond BLAZE_INTERNAL */
1366 /*!\brief Creating a view on a selection of columns on the given matrix transpose operation.
1367 // \ingroup columns
1368 //
1369 // \param matrix The constant matrix transpose operation.
1370 // \param args The runtime column arguments.
1371 // \return View on the specified selection of columns on the transpose operation.
1372 // \exception std::invalid_argument Invalid column access index.
1373 //
1374 // This function returns an expression representing the specified selection of columns on the
1375 // given matrix transpose operation.
1376 */
1377 template< size_t... CCAs    // Compile time column arguments
1378         , typename MT       // Matrix base type of the expression
1379         , typename... RCAs  // Runtime column arguments
1380         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) >* = nullptr >
decltype(auto)1381 inline decltype(auto) columns( const MatTransExpr<MT>& matrix, RCAs... args )
1382 {
1383    BLAZE_FUNCTION_TRACE;
1384 
1385    return trans( rows<CCAs...>( (*matrix).operand(), args... ) );
1386 }
1387 /*! \endcond */
1388 //*************************************************************************************************
1389 
1390 
1391 //*************************************************************************************************
1392 /*! \cond BLAZE_INTERNAL */
1393 /*!\brief Creating a view on a selection of columns on the given column-major vector expansion
1394 //        operation.
1395 // \ingroup columns
1396 //
1397 // \param matrix The constant vector expansion operation.
1398 // \param args The runtime column arguments.
1399 // \return View on the specified selection of columns of the expansion operation.
1400 // \exception std::invalid_argument Invalid column access index.
1401 //
1402 // This function returns an expression representing the specified selection of columns of the
1403 // given column-major vector expansion operation.
1404 */
1405 template< size_t... CCAs    // Compile time column arguments
1406         , typename MT       // Matrix base type of the expression
1407         , size_t... CEAs    // Compile time expansion arguments
1408         , typename... RCAs  // Runtime column arguments
1409         , EnableIf_t< ( sizeof...( CCAs ) > 0UL ) &&
1410                       IsColumnMajorMatrix_v<MT> >* = nullptr >
decltype(auto)1411 inline decltype(auto) columns( const VecExpandExpr<MT,CEAs...>& matrix, RCAs... args )
1412 {
1413    BLAZE_FUNCTION_TRACE;
1414 
1415    if( isChecked( args... ) ) {
1416       constexpr size_t indices[] = { CCAs... };
1417       for( size_t i=0UL; i<sizeof...(CCAs); ++i ) {
1418          if( (*matrix).columns() <= indices[i] ) {
1419             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1420          }
1421       }
1422    }
1423 
1424    return expand< sizeof...( CCAs ) >( (*matrix).operand() );
1425 }
1426 /*! \endcond */
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1431 /*! \cond BLAZE_INTERNAL */
1432 /*!\brief Creating a view on a selection of columns on the given column-major vector expansion
1433 //        operation.
1434 // \ingroup columns
1435 //
1436 // \param matrix The constant vector expansion operation.
1437 // \param indices Pointer to the first index of the selected columns.
1438 // \param n The total number of indices.
1439 // \param args The runtime column arguments.
1440 // \return View on the specified selection of columns of the expansion operation.
1441 // \exception std::invalid_argument Invalid column access index.
1442 //
1443 // This function returns an expression representing the specified selection of columns of the
1444 // given column-major vector expansion operation.
1445 */
1446 template< typename MT       // Matrix base type of the expression
1447         , size_t... CEAs    // Compile time expansion arguments
1448         , typename T        // Type of the column indices or index producer
1449         , typename... RCAs  // Runtime column arguments
1450         , EnableIf_t< IsColumnMajorMatrix_v<MT> >* = nullptr >
decltype(auto)1451 inline decltype(auto) columns( const VecExpandExpr<MT,CEAs...>& matrix, T* indices, size_t n, RCAs... args )
1452 {
1453    BLAZE_FUNCTION_TRACE;
1454 
1455    if( isChecked( args... ) ) {
1456       for( size_t i=0UL; i<n; ++i ) {
1457          if( (*matrix).columns() <= size_t( indices[i] ) ) {
1458             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1459          }
1460       }
1461    }
1462 
1463    return expand( (*matrix).operand(), n );
1464 }
1465 /*! \endcond */
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1470 /*! \cond BLAZE_INTERNAL */
1471 /*!\brief Creating a view on a selection of columns on the given column-major vector expansion
1472 //        operation.
1473 // \ingroup columns
1474 //
1475 // \param matrix The constant vector expansion operation.
1476 // \param p Callable producing the indices.
1477 // \param n The total number of indices.
1478 // \param args The runtime column arguments.
1479 // \return View on the specified selection of columns of the expansion operation.
1480 // \exception std::invalid_argument Invalid column access index.
1481 //
1482 // This function returns an expression representing the specified selection of columns of the
1483 // given column-major vector expansion operation.
1484 */
1485 template< typename MT       // Matrix base type of the expression
1486         , size_t... CEAs    // Compile time expansion arguments
1487         , typename P        // Type of the index producer
1488         , typename... RCAs  // Runtime column arguments
1489         , EnableIf_t< IsColumnMajorMatrix_v<MT> >* = nullptr >
decltype(auto)1490 inline decltype(auto) columns( const VecExpandExpr<MT,CEAs...>& matrix, P p, size_t n, RCAs... args )
1491 {
1492    BLAZE_FUNCTION_TRACE;
1493 
1494    if( isChecked( args... ) ) {
1495       for( size_t i=0UL; i<n; ++i ) {
1496          if( (*matrix).columns() <= size_t( p(i) ) ) {
1497             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1498          }
1499       }
1500    }
1501 
1502    return expand( (*matrix).operand(), n );
1503 }
1504 /*! \endcond */
1505 //*************************************************************************************************
1506 
1507 
1508 //*************************************************************************************************
1509 /*! \cond BLAZE_INTERNAL */
1510 /*!\brief Creating a view on a selection of columns on the given row-major vector expansion operation.
1511 // \ingroup columns
1512 //
1513 // \param matrix The constant vector expansion operation.
1514 // \param args The runtime column arguments.
1515 // \return View on the specified selection of columns of the expansion operation.
1516 // \exception std::invalid_argument Invalid column access index.
1517 //
1518 // This function returns an expression representing the specified selection of columns of the
1519 // given row-major vector expansion operation.
1520 */
1521 template< size_t... CCAs    // Compile time column arguments
1522         , typename MT       // Matrix base type of the expression
1523         , size_t... CEAs    // Compile time expansion arguments
1524         , typename... RCAs  // Runtime column arguments
1525         , EnableIf_t< ( sizeof...( CCAs ) + sizeof...( RCAs ) > 0UL ) &&
1526                       !IsColumnMajorMatrix_v<MT> >* = nullptr >
decltype(auto)1527 inline decltype(auto) columns( const VecExpandExpr<MT,CEAs...>& matrix, RCAs... args )
1528 {
1529    BLAZE_FUNCTION_TRACE;
1530 
1531    try {
1532       return expand<CEAs...>( elements<CCAs...>( (*matrix).operand(), args... ), (*matrix).expansion() );
1533    }
1534    catch( ... ) {
1535       BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1536    }
1537 }
1538 /*! \endcond */
1539 //*************************************************************************************************
1540 
1541 
1542 //*************************************************************************************************
1543 /*! \cond BLAZE_INTERNAL */
1544 /*!\brief Creating a view on a selection of columns on the given matrix repeat operation.
1545 // \ingroup columns
1546 //
1547 // \param matrix The constant matrix repeat operation.
1548 // \param args Optional arguments.
1549 // \return View on the specified selection of columns on the matrix repeat operation.
1550 // \exception std::invalid_argument Invalid column access index.
1551 //
1552 // This function returns an expression representing the specified selection of columns on the
1553 // given matrix repeat operation.
1554 */
1555 template< size_t I            // First column index
1556         , size_t... Is        // Remaining column indices
1557         , typename MT         // Matrix base type of the expression
1558         , size_t... CRAs      // Compile time repeater arguments
1559         , typename... RCAs >  // Optional column arguments
decltype(auto)1560 inline decltype(auto) columns( const MatRepeatExpr<MT,CRAs...>& matrix, RCAs... args )
1561 {
1562    BLAZE_FUNCTION_TRACE;
1563 
1564    if( isChecked( args... ) ) {
1565       constexpr size_t indices[] = { I, Is... };
1566       for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
1567          if( (*matrix).columns() <= indices[i] ) {
1568             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1569          }
1570       }
1571    }
1572 
1573    auto lambda = [columns=(*matrix).operand().columns()]( size_t i ) {
1574       constexpr size_t indices[] = { I, Is... };
1575       return indices[i] % columns;
1576    };
1577 
1578    return repeat( columns( (*matrix).operand(), std::move(lambda), sizeof...(Is)+1UL, unchecked )
1579                 , (*matrix).template repetitions<0UL>(), 1UL );
1580 }
1581 /*! \endcond */
1582 //*************************************************************************************************
1583 
1584 
1585 //*************************************************************************************************
1586 /*! \cond BLAZE_INTERNAL */
1587 /*!\brief Creating a view on a selection of columns on the given matrix repeat operation.
1588 // \ingroup columns
1589 //
1590 // \param matrix The constant matrix repeat operation.
1591 // \param indices Pointer to the first index of the selected columns.
1592 // \param n The total number of indices.
1593 // \param args Optional arguments.
1594 // \return View on the specified selection of columns on the matrix repeat operation.
1595 // \exception std::invalid_argument Invalid column access index.
1596 //
1597 // This function returns an expression representing the specified selection of columns on the
1598 // given matrix repeat operation.
1599 */
1600 template< typename MT         // Matrix base type of the expression
1601         , size_t... CRAs      // Compile time repeater arguments
1602         , typename T          // Type of the column indices
1603         , typename... RCAs >  // Optional column arguments
decltype(auto)1604 inline decltype(auto) columns( const MatRepeatExpr<MT,CRAs...>& matrix, T* indices, size_t n, RCAs... args )
1605 {
1606    BLAZE_FUNCTION_TRACE;
1607 
1608    if( isChecked( args... ) ) {
1609       for( size_t i=0UL; i<n; ++i ) {
1610          if( (*matrix).columns() <= size_t( indices[i] ) ) {
1611             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1612          }
1613       }
1614    }
1615 
1616    SmallArray<size_t,128UL> newIndices( indices, indices+n );
1617 
1618    for( size_t& index : newIndices ) {
1619       index = index % (*matrix).operand().columns();
1620    }
1621 
1622    return repeat( columns( (*matrix).operand(), newIndices, unchecked )
1623                 , (*matrix).template repetitions<0UL>(), 1UL );
1624 }
1625 /*! \endcond */
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1630 /*! \cond BLAZE_INTERNAL */
1631 /*!\brief Creating a view on a selection of columns on the given matrix repeat operation.
1632 // \ingroup columns
1633 //
1634 // \param matrix The constant matrix repeat operation.
1635 // \param p Callable producing the indices.
1636 // \param n The total number of indices.
1637 // \param args Optional arguments.
1638 // \return View on the specified selection of columns on the matrix repeat operation.
1639 // \exception std::invalid_argument Invalid column access index.
1640 //
1641 // This function returns an expression representing the specified selection of columns on the
1642 // given matrix repeat operation.
1643 */
1644 template< typename MT         // Matrix base type of the expression
1645         , size_t... CRAs      // Compile time repeater arguments
1646         , typename P          // Type of the index producer
1647         , typename... RCAs >  // Optional column arguments
decltype(auto)1648 inline decltype(auto) columns( const MatRepeatExpr<MT,CRAs...>& matrix, P p, size_t n, RCAs... args )
1649 {
1650    BLAZE_FUNCTION_TRACE;
1651 
1652    if( isChecked( args... ) ) {
1653       for( size_t i=0UL; i<n; ++i ) {
1654          if( (*matrix).columns() <= size_t( p(i) ) ) {
1655             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1656          }
1657       }
1658    }
1659 
1660    auto lambda = [columns=(*matrix).operand().columns(),p]( size_t i ) {
1661       return p(i) % columns;
1662    };
1663 
1664    return repeat( columns( (*matrix).operand(), std::move(lambda), n, unchecked )
1665                 , (*matrix).template repetitions<0UL>(), 1UL );
1666 }
1667 /*! \endcond */
1668 //*************************************************************************************************
1669 
1670 
1671 
1672 
1673 //=================================================================================================
1674 //
1675 //  GLOBAL RESTRUCTURING FUNCTIONS (COLUMNS)
1676 //
1677 //=================================================================================================
1678 
1679 //*************************************************************************************************
1680 /*! \cond BLAZE_INTERNAL */
1681 /*!\brief Creating a view on specific columns of the given column selection.
1682 // \ingroup columns
1683 //
1684 // \param c The selection of columns containing the columns.
1685 // \param args The optional column arguments.
1686 // \return View on the specified columns of the column selection.
1687 //
1688 // This function returns an expression representing the specified columns of the given column
1689 // selection.
1690 */
1691 template< size_t I          // First required column index
1692         , size_t... Is      // Remaining required column indices
1693         , typename MT       // Type of the matrix
1694         , typename... RCAs  // Optional column arguments
1695         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > &&
1696                       RemoveReference_t<MT>::compileTimeArgs >* = nullptr >
decltype(auto)1697 inline decltype(auto) columns( MT&& c, RCAs... args )
1698 {
1699    BLAZE_FUNCTION_TRACE;
1700 
1701    return columns( c.operand(), subsequence<I,Is...>( RemoveReference_t<MT>::idces() ), args... );
1702 }
1703 /*! \endcond */
1704 //*************************************************************************************************
1705 
1706 
1707 //*************************************************************************************************
1708 /*! \cond BLAZE_INTERNAL */
1709 /*!\brief Creating a view on specific columns of the given column selection.
1710 // \ingroup columns
1711 //
1712 // \param c The selection of columns containing the columns.
1713 // \param args The optional column arguments.
1714 // \return View on the specified columns of the column selection.
1715 // \exception std::invalid_argument Invalid column access index.
1716 //
1717 // This function returns an expression representing the specified columns of the given column
1718 // selection.
1719 */
1720 template< size_t I          // First required column index
1721         , size_t... Is      // Remaining required column indices
1722         , typename MT       // Type of the matrix
1723         , typename... RCAs  // Optional column arguments
1724         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > &&
1725                       !RemoveReference_t<MT>::compileTimeArgs >* = nullptr >
decltype(auto)1726 inline decltype(auto) columns( MT&& c, RCAs... args )
1727 {
1728    BLAZE_FUNCTION_TRACE;
1729 
1730    if( isChecked( args... ) ) {
1731       constexpr size_t indices[] = { I, Is... };
1732       for( size_t i=0UL; i<sizeof...(Is)+1UL; ++i ) {
1733          if( c.columns() <= indices[i] ) {
1734             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1735          }
1736       }
1737    }
1738 
1739    return columns( c.operand(), { c.idx(I), c.idx(Is)... }, unchecked );
1740 }
1741 /*! \endcond */
1742 //*************************************************************************************************
1743 
1744 
1745 //*************************************************************************************************
1746 /*! \cond BLAZE_INTERNAL */
1747 /*!\brief Creating a view on specific columns of the given column selection.
1748 // \ingroup columns
1749 //
1750 // \param c The selection of columns containing the columns.
1751 // \param indices Pointer to the first index of the selected columns.
1752 // \param n The total number of indices.
1753 // \param args The optional column arguments.
1754 // \return View on the specified columns of the column selection.
1755 // \exception std::invalid_argument Invalid column access index.
1756 //
1757 // This function returns an expression representing the specified column of the given column
1758 // selection.
1759 */
1760 template< typename MT       // Type of the matrix
1761         , typename T        // Type of the column indices
1762         , typename... RCAs  // Optional column arguments
1763         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > >* = nullptr >
decltype(auto)1764 inline decltype(auto) columns( MT&& c, T* indices, size_t n, RCAs... args )
1765 {
1766    BLAZE_FUNCTION_TRACE;
1767 
1768    if( isChecked( args... ) ) {
1769       for( size_t i=0UL; i<n; ++i ) {
1770          if( c.columns() <= size_t( indices[i] ) ) {
1771             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1772          }
1773       }
1774    }
1775 
1776    SmallArray<size_t,128UL> newIndices;
1777    newIndices.reserve( n );
1778 
1779    for( size_t i=0UL; i<n; ++i ) {
1780       newIndices.pushBack( c.idx( indices[i] ) );
1781    }
1782 
1783    return columns( c.operand(), newIndices.data(), newIndices.size(), unchecked );
1784 }
1785 /*! \endcond */
1786 //*************************************************************************************************
1787 
1788 
1789 //*************************************************************************************************
1790 /*! \cond BLAZE_INTERNAL */
1791 /*!\brief Creating a view on specific columns of the given column selection.
1792 // \ingroup columns
1793 //
1794 // \param c The selection of columns containing the columns.
1795 // \param p Callable producing the indices.
1796 // \param n The total number of indices.
1797 // \param args The optional column arguments.
1798 // \return View on the specified columns of the column selection.
1799 // \exception std::invalid_argument Invalid column access index.
1800 //
1801 // This function returns an expression representing the specified column of the given column
1802 // selection.
1803 */
1804 template< typename MT       // Type of the matrix
1805         , typename P        // Type of the index producer
1806         , typename... RCAs  // Optional column arguments
1807         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > && !IsPointer_v<P> >* = nullptr >
decltype(auto)1808 inline decltype(auto) columns( MT&& c, P p, size_t n, RCAs... args )
1809 {
1810    BLAZE_FUNCTION_TRACE;
1811 
1812    if( isChecked( args... ) ) {
1813       for( size_t i=0UL; i<n; ++i ) {
1814          if( c.columns() <= size_t( p(i) ) ) {
1815             BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
1816          }
1817       }
1818    }
1819 
1820    SmallArray<size_t,128UL> newIndices;
1821    newIndices.reserve( n );
1822 
1823    for( size_t i=0UL; i<n; ++i ) {
1824       newIndices.pushBack( c.idx( p(i) ) );
1825    }
1826 
1827    return columns( c.operand(), newIndices.data(), newIndices.size(), unchecked );
1828 }
1829 /*! \endcond */
1830 //*************************************************************************************************
1831 
1832 
1833 
1834 
1835 //=================================================================================================
1836 //
1837 //  GLOBAL RESTRUCTURING FUNCTIONS (ELEMENTS)
1838 //
1839 //=================================================================================================
1840 
1841 //*************************************************************************************************
1842 /*! \cond BLAZE_INTERNAL */
1843 /*!\brief Creating a view on a selection of elements of the given vector/matrix multiplication.
1844 // \ingroup columns
1845 //
1846 // \param vector The constant vector/matrix multiplication.
1847 // \param args The runtime element arguments.
1848 // \return View on the specified elements of the multiplication.
1849 // \exception std::invalid_argument Invalid element access index.
1850 //
1851 // This function returns an expression representing the specified elements of the given
1852 // vector/matrix multiplication.
1853 */
1854 template< size_t... CEAs      // Compile time element arguments
1855         , typename VT         // Vector base type of the expression
1856         , typename... REAs >  // Runtime element arguments
decltype(auto)1857 inline decltype(auto) elements( const TVecMatMultExpr<VT>& vector, REAs... args )
1858 {
1859    BLAZE_FUNCTION_TRACE;
1860 
1861    try {
1862       return (*vector).leftOperand() * columns<CEAs...>( (*vector).rightOperand(), args... );
1863    }
1864    catch( ... ) {
1865       BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
1866    }
1867 }
1868 /*! \endcond */
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1873 /*! \cond BLAZE_INTERNAL */
1874 /*!\brief Creating a view on a selection of elements of the given column-wise matrix reduction
1875 //        operation.
1876 // \ingroup columns
1877 //
1878 // \param vector The constant column-wise matrix reduction operation.
1879 // \param args The runtime element arguments.
1880 // \return View on the specified elements of the multiplication.
1881 // \exception std::invalid_argument Invalid element access index.
1882 //
1883 // This function returns an expression representing the specified elements of the given
1884 // column-wise matrix reduction operation.
1885 */
1886 template< size_t... CEAs      // Compile time element arguments
1887         , typename VT         // Vector base type of the expression
1888         , typename... REAs >  // Runtime element arguments
decltype(auto)1889 inline decltype(auto) elements( const MatReduceExpr<VT,columnwise>& vector, REAs... args )
1890 {
1891    BLAZE_FUNCTION_TRACE;
1892 
1893    try {
1894       return reduce<columnwise>( columns<CEAs...>( (*vector).operand(), args... ), (*vector).operation() );
1895    }
1896    catch( ... ) {
1897       BLAZE_THROW_INVALID_ARGUMENT( "Invalid element access index" );
1898    }
1899 }
1900 /*! \endcond */
1901 //*************************************************************************************************
1902 
1903 
1904 
1905 
1906 //=================================================================================================
1907 //
1908 //  GLOBAL RESTRUCTURING FUNCTIONS (ROW)
1909 //
1910 //=================================================================================================
1911 
1912 //*************************************************************************************************
1913 /*! \cond BLAZE_INTERNAL */
1914 /*!\brief Creating a view on a specific row of the given column selection.
1915 // \ingroup columns
1916 //
1917 // \param columns The selection of columns containing the row.
1918 // \param args The runtime row arguments.
1919 // \return View on the specified row of the column selection.
1920 // \exception std::invalid_argument Invalid row access index.
1921 //
1922 // This function returns an expression representing the specified row of the given column selection.
1923 */
1924 template< size_t... CRAs    // Compile time row arguments
1925         , typename MT       // Type of the matrix
1926         , typename... RRAs  // Runtime row arguments
1927         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > >* = nullptr >
decltype(auto)1928 inline decltype(auto) row( MT&& columns, RRAs... args )
1929 {
1930    BLAZE_FUNCTION_TRACE;
1931 
1932    return elements( row<CRAs...>( columns.operand(), args... ), columns.idces() );
1933 }
1934 /*! \endcond */
1935 //*************************************************************************************************
1936 
1937 
1938 
1939 
1940 //=================================================================================================
1941 //
1942 //  GLOBAL RESTRUCTURING FUNCTIONS (COLUMN)
1943 //
1944 //=================================================================================================
1945 
1946 //*************************************************************************************************
1947 /*! \cond BLAZE_INTERNAL */
1948 /*!\brief Creating a view on a specific column of the given column selection.
1949 // \ingroup columns
1950 //
1951 // \param columns The selection of columns containing the column.
1952 // \param args The optional column arguments.
1953 // \return View on the specified column of the column selection.
1954 //
1955 // This function returns an expression representing the specified column of the given column
1956 // selection.
1957 */
1958 template< size_t I          // Column index
1959         , typename MT       // Type of the matrix
1960         , typename... RCAs  // Optional column arguments
1961         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > &&
1962                       RemoveReference_t<MT>::compileTimeArgs >* = nullptr >
decltype(auto)1963 inline decltype(auto) column( MT&& columns, RCAs... args )
1964 {
1965    BLAZE_FUNCTION_TRACE;
1966 
1967    return column< RemoveReference_t<MT>::idx(I) >( columns.operand(), args... );
1968 }
1969 /*! \endcond */
1970 //*************************************************************************************************
1971 
1972 
1973 //*************************************************************************************************
1974 /*! \cond BLAZE_INTERNAL */
1975 /*!\brief Creating a view on a specific column of the given column selection.
1976 // \ingroup columns
1977 //
1978 // \param columns The selection of columns containing the column.
1979 // \param args The runtime column arguments.
1980 // \return View on the specified column of the column selection.
1981 // \exception std::invalid_argument Invalid column access index.
1982 //
1983 // This function returns an expression representing the specified column of the given column
1984 // selection.
1985 */
1986 template< size_t... CCAs    // Compile time column arguments
1987         , typename MT       // Type of the matrix
1988         , typename... RCAs  // Runtime column arguments
1989         , EnableIf_t< IsColumns_v< RemoveReference_t<MT> > &&
1990                       ( sizeof...( CCAs ) == 0UL || !RemoveReference_t<MT>::compileTimeArgs ) >* = nullptr >
decltype(auto)1991 inline decltype(auto) column( MT&& columns, RCAs... args )
1992 {
1993    BLAZE_FUNCTION_TRACE;
1994 
1995    const ColumnData<CCAs...> cd( args... );
1996 
1997    if( isChecked( args... ) ) {
1998       if( columns.columns() <= cd.column() ) {
1999          BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2000       }
2001    }
2002 
2003    return column( columns.operand(), columns.idx( cd.column() ), args... );
2004 }
2005 /*! \endcond */
2006 //*************************************************************************************************
2007 
2008 
2009 
2010 
2011 //=================================================================================================
2012 //
2013 //  COLUMNS OPERATORS
2014 //
2015 //=================================================================================================
2016 
2017 //*************************************************************************************************
2018 /*! \cond BLAZE_INTERNAL */
2019 /*!\brief Resetting the given column selection.
2020 // \ingroup columns
2021 //
2022 // \param columns The column selection to be resetted.
2023 // \return void
2024 */
2025 template< typename MT         // Type of the matrix
2026         , bool SO             // Storage order
2027         , bool DF             // Density flag
2028         , bool SF             // Symmetry flag
2029         , typename... CCAs >  // Compile time column arguments
reset(Columns<MT,SO,DF,SF,CCAs...> & columns)2030 inline void reset( Columns<MT,SO,DF,SF,CCAs...>& columns )
2031 {
2032    columns.reset();
2033 }
2034 /*! \endcond */
2035 //*************************************************************************************************
2036 
2037 
2038 //*************************************************************************************************
2039 /*! \cond BLAZE_INTERNAL */
2040 /*!\brief Resetting the given temporary column selection.
2041 // \ingroup columns
2042 //
2043 // \param columns The temporary column selection to be resetted.
2044 // \return void
2045 */
2046 template< typename MT         // Type of the matrix
2047         , bool SO             // Storage order
2048         , bool DF             // Density flag
2049         , bool SF             // Symmetry flag
2050         , typename... CCAs >  // Compile time column arguments
reset(Columns<MT,SO,DF,SF,CCAs...> && columns)2051 inline void reset( Columns<MT,SO,DF,SF,CCAs...>&& columns )
2052 {
2053    columns.reset();
2054 }
2055 /*! \endcond */
2056 //*************************************************************************************************
2057 
2058 
2059 //*************************************************************************************************
2060 /*! \cond BLAZE_INTERNAL */
2061 /*!\brief Reset the specified column of the given column selection.
2062 // \ingroup columns
2063 //
2064 // \param columns The column selection to be resetted.
2065 // \param i The index of the column to be resetted.
2066 // \return void
2067 //
2068 // This function resets the values in the specified column of the given column selection to their
2069 // default value. Note that the capacity of the column remains unchanged.
2070 */
2071 template< typename MT         // Type of the matrix
2072         , bool SO             // Storage order
2073         , bool DF             // Density flag
2074         , bool SF             // Symmetry flag
2075         , typename... CCAs >  // Compile time column arguments
reset(Columns<MT,SO,DF,SF,CCAs...> & columns,size_t i)2076 inline void reset( Columns<MT,SO,DF,SF,CCAs...>& columns, size_t i )
2077 {
2078    columns.reset( i );
2079 }
2080 /*! \endcond */
2081 //*************************************************************************************************
2082 
2083 
2084 //*************************************************************************************************
2085 /*! \cond BLAZE_INTERNAL */
2086 /*!\brief Clearing the given column selection.
2087 // \ingroup columns
2088 //
2089 // \param columns The column selection to be cleared.
2090 // \return void
2091 //
2092 // Clearing a column selection is equivalent to resetting it via the reset() function.
2093 */
2094 template< typename MT         // Type of the matrix
2095         , bool SO             // Storage order
2096         , bool DF             // Density flag
2097         , bool SF             // Symmetry flag
2098         , typename... CCAs >  // Compile time column arguments
clear(Columns<MT,SO,DF,SF,CCAs...> & columns)2099 inline void clear( Columns<MT,SO,DF,SF,CCAs...>& columns )
2100 {
2101    columns.reset();
2102 }
2103 /*! \endcond */
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2108 /*! \cond BLAZE_INTERNAL */
2109 /*!\brief Clearing the given temporary column selection.
2110 // \ingroup columns
2111 //
2112 // \param columns The column selection to be cleared.
2113 // \return void
2114 //
2115 // Clearing a column selection is equivalent to resetting it via the reset() function.
2116 */
2117 template< typename MT         // Type of the matrix
2118         , bool SO             // Storage order
2119         , bool DF             // Density flag
2120         , bool SF             // Symmetry flag
2121         , typename... CCAs >  // Compile time column arguments
clear(Columns<MT,SO,DF,SF,CCAs...> && columns)2122 inline void clear( Columns<MT,SO,DF,SF,CCAs...>&& columns )
2123 {
2124    columns.reset();
2125 }
2126 /*! \endcond */
2127 //*************************************************************************************************
2128 
2129 
2130 //*************************************************************************************************
2131 /*! \cond BLAZE_INTERNAL */
2132 /*!\brief Returns whether the given dense column selection is in default state.
2133 // \ingroup columns
2134 //
2135 // \param columns The dense column selection to be tested for its default state.
2136 // \return \a true in case the given dense column selection is component-wise zero, \a false otherwise.
2137 //
2138 // This function checks whether the dense column selection is in default state. For instance, in
2139 // case the column selection is instantiated for a built-in integral or floating point data type,
2140 // the function returns \a true in case all column elements are 0 and \a false in case any column
2141 // element is not 0. The following example demonstrates the use of the \a isDefault function:
2142 
2143    \code
2144    blaze::DynamicMatrix<double,columnMajor> A;
2145    // ... Resizing and initialization
2146    if( isDefault( columns( A, { 2UL, 4UL, 6UL, 8UL } ) ) ) { ... }
2147    \endcode
2148 
2149 // Optionally, it is possible to switch between strict semantics (blaze::strict) and relaxed
2150 // semantics (blaze::relaxed):
2151 
2152    \code
2153    if( isDefault<relaxed>( columns( A, { 2UL, 4UL, 6UL, 8UL } ) ) ) { ... }
2154    \endcode
2155 */
2156 template< RelaxationFlag RF   // Relaxation flag
2157         , typename MT         // Type of the dense matrix
2158         , bool SO             // Storage order
2159         , bool SF             // Symmetry flag
2160         , typename... CCAs >  // Compile time column arguments
isDefault(const Columns<MT,SO,true,SF,CCAs...> & columns)2161 inline bool isDefault( const Columns<MT,SO,true,SF,CCAs...>& columns )
2162 {
2163    using blaze::isDefault;
2164 
2165    if( SO == false ) {
2166       for( size_t i=0UL; i<columns.rows(); ++i )
2167          for( size_t j=0UL; j<columns.columns(); ++j )
2168             if( !isDefault<RF>( columns(i,j) ) )
2169                return false;
2170    }
2171    else {
2172       for( size_t j=0UL; j<columns.columns(); ++j )
2173          for( size_t i=0UL; i<columns.rows(); ++i )
2174             if( !isDefault<RF>( columns(i,j) ) )
2175                return false;
2176    }
2177 
2178    return true;
2179 }
2180 /*! \endcond */
2181 //*************************************************************************************************
2182 
2183 
2184 //*************************************************************************************************
2185 /*! \cond BLAZE_INTERNAL */
2186 /*!\brief Returns whether the given sparse column selection is in default state.
2187 // \ingroup columns
2188 //
2189 // \param columns The sparse column selection to be tested for its default state.
2190 // \return \a true in case the given sparse column selection is component-wise zero, \a false otherwise.
2191 //
2192 // This function checks whether the sparse column selection is in default state. For instance, in
2193 // case the column selection is instantiated for a built-in integral or floating point data type,
2194 // the function returns \a true in case all column elements are 0 and \a false in case any column
2195 // element is not 0. The following example demonstrates the use of the \a isDefault function:
2196 
2197    \code
2198    blaze::CompressedMatrix<double,columnMajor> A;
2199    // ... Resizing and initialization
2200    if( isDefault( columns( A, { 2UL, 4UL, 6UL, 8UL } ) ) ) { ... }
2201    \endcode
2202 
2203 // Optionally, it is possible to switch between strict semantics (blaze::strict) and relaxed
2204 // semantics (blaze::relaxed):
2205 
2206    \code
2207    if( isDefault<relaxed>( columns( A, { 2UL, 4UL, 6UL, 8UL } ) ) ) { ... }
2208    \endcode
2209 */
2210 template< RelaxationFlag RF   // Relaxation flag
2211         , typename MT         // Type of the dense matrix
2212         , bool SO             // Storage order
2213         , bool SF             // Symmetry flag
2214         , typename... CCAs >  // Compile time column arguments
isDefault(const Columns<MT,SO,false,SF,CCAs...> & columns)2215 inline bool isDefault( const Columns<MT,SO,false,SF,CCAs...>& columns )
2216 {
2217    using blaze::isDefault;
2218 
2219    for( size_t j=0UL; j<columns.columns(); ++j ) {
2220       for( auto element=columns.cbegin(j); element!=columns.cend(j); ++element )
2221          if( !isDefault<RF>( element->value() ) ) return false;
2222    }
2223 
2224    return true;
2225 }
2226 /*! \endcond */
2227 //*************************************************************************************************
2228 
2229 
2230 //*************************************************************************************************
2231 /*! \cond BLAZE_INTERNAL */
2232 /*!\brief Returns whether the invariants of the given column selection are intact.
2233 // \ingroup columns
2234 //
2235 // \param columns The column selection to be tested.
2236 // \return \a true in case the given column selection's invariants are intact, \a false otherwise.
2237 //
2238 // This function checks whether the invariants of the column selection are intact, i.e. if its
2239 // state is valid. In case the invariants are intact, the function returns \a true, else it will
2240 // return \a false. The following example demonstrates the use of the \a isIntact() function:
2241 
2242    \code
2243    blaze::DynamicMatrix<double,columnMajor> A;
2244    // ... Resizing and initialization
2245    if( isIntact( columns( A, { 2UL, 4UL, 6UL, 8UL } ) ) ) { ... }
2246    \endcode
2247 */
2248 template< typename MT         // Type of the matrix
2249         , bool SO             // Storage order
2250         , bool DF             // Density flag
2251         , bool SF             // Symmetry flag
2252         , typename... CCAs >  // Compile time column arguments
isIntact(const Columns<MT,SO,DF,SF,CCAs...> & columns)2253 inline bool isIntact( const Columns<MT,SO,DF,SF,CCAs...>& columns ) noexcept
2254 {
2255    return ( columns.rows() == columns.operand().rows() &&
2256             columns.columns() <= columns.operand().columns() &&
2257             isIntact( columns.operand() ) );
2258 }
2259 /*! \endcond */
2260 //*************************************************************************************************
2261 
2262 
2263 //*************************************************************************************************
2264 /*! \cond BLAZE_INTERNAL */
2265 /*!\brief Returns whether the given column selection and matrix represent the same observable state.
2266 // \ingroup columns
2267 //
2268 // \param a The column selection to be tested for its state.
2269 // \param b The matrix to be tested for its state.
2270 // \return \a true in case the column selection and matrix share a state, \a false otherwise.
2271 //
2272 // This overload of the isSame function tests if the given column selection refers to all columns
2273 // of the given matrix in ascending and consecutive order and by that represents the same observable
2274 // state. In this case, the function returns \a true, otherwise it returns \a false.
2275 */
2276 template< typename MT       // Type of the matrix
2277         , bool SO1          // Storage order of the left-hand side column selection
2278         , bool DF           // Density flag
2279         , bool SF           // Symmetry flag
2280         , typename... CCAs  // Compile time column arguments
2281         , bool SO2 >        // Storage order of the right-hand side matrix
isSame(const Columns<MT,SO1,DF,SF,CCAs...> & a,const Matrix<MT,SO2> & b)2282 inline bool isSame( const Columns<MT,SO1,DF,SF,CCAs...>& a, const Matrix<MT,SO2>& b ) noexcept
2283 {
2284    if( !isSame( a.operand(), *b ) || ( a.rows() != (*b).rows() ) || ( a.columns() != (*b).columns() ) )
2285       return false;
2286 
2287    for( size_t j=0UL; j<a.columns(); ++j ) {
2288       if( a.idx(j) != j )
2289          return false;
2290    }
2291 
2292    return true;
2293 }
2294 /*! \endcond */
2295 //*************************************************************************************************
2296 
2297 
2298 //*************************************************************************************************
2299 /*! \cond BLAZE_INTERNAL */
2300 /*!\brief Returns whether the given matrix and column selection represent the same observable state.
2301 // \ingroup columns
2302 //
2303 // \param a The matrix to be tested for its state.
2304 // \param b The column selection to be tested for its state.
2305 // \return \a true in case the matrix and column selection share a state, \a false otherwise.
2306 //
2307 // This overload of the isSame function tests if the given column selection refers to all columns
2308 // of the given matrix in ascending and consecutive order and by that represents the same observable
2309 // state. In this case, the function returns \a true, otherwise it returns \a false.
2310 */
2311 template< typename MT       // Type of the matrix
2312         , bool SO1          // Storage order of the left-hand side matrix
2313         , bool DF           // Density flag
2314         , bool SF           // Symmetry flag
2315         , typename... CCAs  // Compile time column arguments
2316         , bool SO2 >        // Storage order of the right-hand side column selection
isSame(const Matrix<MT,SO1> & a,const Columns<MT,SO2,DF,SF,CCAs...> & b)2317 inline bool isSame( const Matrix<MT,SO1>& a, const Columns<MT,SO2,DF,SF,CCAs...>& b ) noexcept
2318 {
2319    return isSame( b, a );
2320 }
2321 /*! \endcond */
2322 //*************************************************************************************************
2323 
2324 
2325 //*************************************************************************************************
2326 /*! \cond BLAZE_INTERNAL */
2327 /*!\brief Returns whether the given column selection and submatrix represent the same observable state.
2328 // \ingroup columns
2329 //
2330 // \param a The column selection to be tested for its state.
2331 // \param b The submatrix to be tested for its state.
2332 // \return \a true in case the column selection and submatrix share a state, \a false otherwise.
2333 //
2334 // This overload of the isSame function tests if the given column selection refers to same columns
2335 // as the given submatrix in ascending and consecutive order and by that represents the same
2336 // observable state. In this case, the function returns \a true, otherwise it returns \a false.
2337 */
2338 template< typename MT       // Type of the matrix
2339         , bool SO1          // Storage order of the left-hand side column selection
2340         , bool DF           // Density flag
2341         , bool SF           // Symmetry flag
2342         , typename... CCAs  // Compile time column arguments
2343         , AlignmentFlag AF  // Alignment flag
2344         , bool SO2          // Storage order of the right-hand side submatrix
2345         , size_t... CSAs >  // Compile time submatrix arguments
isSame(const Columns<MT,SO1,DF,SF,CCAs...> & a,const Submatrix<MT,AF,SO2,DF,CSAs...> & b)2346 inline bool isSame( const Columns<MT,SO1,DF,SF,CCAs...>& a, const Submatrix<MT,AF,SO2,DF,CSAs...>& b ) noexcept
2347 {
2348    if( !isSame( a.operand(), b.operand() ) || ( a.rows() != (*b).rows() ) || ( a.columns() != (*b).columns() ) )
2349       return false;
2350 
2351    for( size_t j=0UL; j<a.columns(); ++j ) {
2352       if( a.idx(j) != b.column()+j )
2353          return false;
2354    }
2355 
2356    return true;
2357 }
2358 /*! \endcond */
2359 //*************************************************************************************************
2360 
2361 
2362 //*************************************************************************************************
2363 /*! \cond BLAZE_INTERNAL */
2364 /*!\brief Returns whether the given submatrix and column selection represent the same observable state.
2365 // \ingroup columns
2366 //
2367 // \param a The submatrix to be tested for its state.
2368 // \param b The column selection to be tested for its state.
2369 // \return \a true in case the submatrix and column selection share a state, \a false otherwise.
2370 //
2371 // This overload of the isSame function tests if the given column selection refers to same columns
2372 // as the given submatrix in ascending and consecutive order and by that represents the same
2373 // observable state. In this case, the function returns \a true, otherwise it returns \a false.
2374 */
2375 template< typename MT         // Type of the matrix
2376         , AlignmentFlag AF    // Alignment flag
2377         , bool SO1            // Storage order of the left-hand side submatrix
2378         , bool DF             // Density flag
2379         , size_t... CSAs      // Compile time submatrix arguments
2380         , bool SO2            // Storage order of the right-hand side column selection
2381         , bool SF             // Symmetry flag
2382         , typename... CCAs >  // Compile time column arguments
isSame(const Submatrix<MT,AF,SO1,DF,CSAs...> & a,const Columns<MT,SO2,DF,SF,CCAs...> & b)2383 inline bool isSame( const Submatrix<MT,AF,SO1,DF,CSAs...>& a, const Columns<MT,SO2,DF,SF,CCAs...>& b ) noexcept
2384 {
2385    return isSame( b, a );
2386 }
2387 /*! \endcond */
2388 //*************************************************************************************************
2389 
2390 
2391 //*************************************************************************************************
2392 /*! \cond BLAZE_INTERNAL */
2393 /*!\brief Returns whether the two given column selections represent the same observable state.
2394 // \ingroup columns
2395 //
2396 // \param a The first selection of columns to be tested for its state.
2397 // \param b The second selection of columns to be tested for its state.
2398 // \return \a true in case the two column selections share a state, \a false otherwise.
2399 //
2400 // This overload of the isSame function tests if the two given column selections refer to exactly
2401 // the same range of the same matrix. In case both selections represent the same observable
2402 // state, the function returns \a true, otherwise it returns \a false.
2403 */
2404 template< typename MT          // Type of the matrix
2405         , bool SO              // Storage order
2406         , bool DF              // Density flag
2407         , bool SF              // Symmetry flag
2408         , typename... CCAs1    // Compile time column arguments of the left-hand side column selection
2409         , typename... CCAs2 >  // Compile time column arguments of the right-hand side column selection
isSame(const Columns<MT,SO,DF,SF,CCAs1...> & a,const Columns<MT,SO,DF,SF,CCAs2...> & b)2410 inline bool isSame( const Columns<MT,SO,DF,SF,CCAs1...>& a,
2411                     const Columns<MT,SO,DF,SF,CCAs2...>& b ) noexcept
2412 {
2413    if( !isSame( a.operand(), b.operand() ) || a.rows() != b.rows() || a.columns() != b.columns() )
2414       return false;
2415 
2416    for( size_t i=0UL; i<a.columns(); ++i ) {
2417       if( a.idx(i) != b.idx(i) )
2418          return false;
2419    }
2420 
2421    return true;
2422 }
2423 /*! \endcond */
2424 //*************************************************************************************************
2425 
2426 
2427 //*************************************************************************************************
2428 /*! \cond BLAZE_INTERNAL */
2429 /*!\brief In-place inversion of the given dense column selection.
2430 // \ingroup columns
2431 //
2432 // \param c The dense column selection to be inverted.
2433 // \return void
2434 // \exception std::invalid_argument Invalid non-square matrix provided.
2435 // \exception std::invalid_argument Inversion of singular matrix failed.
2436 //
2437 // This function inverts the given dense column selection by means of the specified matrix type
2438 // or matrix inversion algorithm \c IF (see the InversionFlag documentation):
2439 
2440    \code
2441    invert<asLower>( A );     // Inversion of a lower triangular matrix
2442    invert<asUniUpper>( A );  // Inversion of an upper unitriangular matrix
2443    invert<byLU>( A );        // Inversion by means of an LU decomposition
2444    invert<byLLH>( A );       // Inversion by means of a Cholesky decomposition
2445    ...
2446    \endcode
2447 
2448 // The matrix inversion fails if ...
2449 //
2450 //  - ... the given column selection is not a square matrix;
2451 //  - ... the given column selection is singular and not invertible.
2452 //
2453 // In all failure cases either a compilation error is created if the failure can be predicted at
2454 // compile time or an exception is thrown.
2455 //
2456 // \note The matrix inversion can only be used for dense matrices with \c float, \c double,
2457 // \c complex<float> or \c complex<double> element type. The attempt to call the function with
2458 // matrices of any other element type results in a compile time error!
2459 //
2460 // \note This function can only be used if a fitting LAPACK library is available and linked to
2461 // the executable. Otherwise a linker error will be created.
2462 //
2463 // \note This function does only provide the basic exception safety guarantee, i.e. in case of an
2464 // exception \a c may already have been modified.
2465 */
2466 template< InversionFlag IF    // Inversion algorithm
2467         , typename MT         // Type of the dense matrix
2468         , bool SO             // Storage order
2469         , bool SF             // Symmetry flag
2470         , typename... CCAs >  // Compile time column arguments
2471 inline auto invert( Columns<MT,SO,true,SF,CCAs...>& c )
2472    -> DisableIf_t< HasMutableDataAccess_v<MT> >
2473 {
2474    using RT = ResultType_t< Columns<MT,SO,true,SF,CCAs...> >;
2475 
2476    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION  ( RT );
2477    BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS( RT );
2478 
2479    RT tmp( c );
2480    invert<IF>( tmp );
2481    c = tmp;
2482 }
2483 /*! \endcond */
2484 //*************************************************************************************************
2485 
2486 
2487 //*************************************************************************************************
2488 /*! \cond BLAZE_INTERNAL */
2489 /*!\brief Predict invariant violations by setting a single element of a column selection.
2490 // \ingroup columns
2491 //
2492 // \param c The target column selection.
2493 // \param i The row index of the element to be set.
2494 // \param j The column index of the element to be set.
2495 // \param value The value to be set to the element.
2496 // \return \a true in case the operation would be successful, \a false if not.
2497 //
2498 // This function must \b NOT be called explicitly! It is used internally for the performance
2499 // optimized evaluation of expression templates. Calling this function explicitly might result
2500 // in erroneous results and/or in compilation errors. Instead of using this function use the
2501 // assignment operator.
2502 */
2503 template< typename MT       // Type of the matrix
2504         , bool SO           // Storage order
2505         , bool DF           // Density flag
2506         , bool SF           // Symmetry flag
2507         , typename... CCAs  // Compile time column arguments
2508         , typename ET >     // Type of the element
trySet(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2509 inline bool trySet( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2510 {
2511    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2512    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2513 
2514    return trySet( c.operand(), c.idx(i), j, value );
2515 }
2516 /*! \endcond */
2517 //*************************************************************************************************
2518 
2519 
2520 //*************************************************************************************************
2521 /*! \cond BLAZE_INTERNAL */
2522 /*!\brief Predict invariant violations by setting a range of elements of a column selection.
2523 // \ingroup columns
2524 //
2525 // \param c The target column selection.
2526 // \param row The index of the first row of the range to be modified.
2527 // \param column The index of the first column of the range to be modified.
2528 // \param m The number of rows of the range to be modified.
2529 // \param n The number of columns of the range to be modified.
2530 // \param value The value to be set to the range of elements.
2531 // \return \a true in case the operation would be successful, \a false if not.
2532 //
2533 // This function must \b NOT be called explicitly! It is used internally for the performance
2534 // optimized evaluation of expression templates. Calling this function explicitly might result
2535 // in erroneous results and/or in compilation errors. Instead of using this function use the
2536 // assignment operator.
2537 */
2538 template< typename MT       // Type of the matrix
2539         , bool SO           // Storage order
2540         , bool DF           // Density flag
2541         , bool SF           // Symmetry flag
2542         , typename... CCAs  // Compile time column arguments
2543         , typename ET >     // Type of the element
2544 BLAZE_ALWAYS_INLINE bool
trySet(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)2545    trySet( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
2546 {
2547    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2548    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2549    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2550    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2551 
2552    const size_t jend( column + n );
2553 
2554    for( size_t j=column; j<jend; ++j ) {
2555       if( !trySet( c.operand(), row, c.idx(j), m, 1UL, value ) )
2556          return false;
2557    }
2558 
2559    return true;
2560 }
2561 /*! \endcond */
2562 //*************************************************************************************************
2563 
2564 
2565 //*************************************************************************************************
2566 /*! \cond BLAZE_INTERNAL */
2567 /*!\brief Predict invariant violations by adding to a single element of a column selection.
2568 // \ingroup columns
2569 //
2570 // \param c The target column selection.
2571 // \param i The row index of the element to be modified.
2572 // \param j The column index of the element to be modified.
2573 // \param value The value to be added to the element.
2574 // \return \a true in case the operation would be successful, \a false if not.
2575 //
2576 // This function must \b NOT be called explicitly! It is used internally for the performance
2577 // optimized evaluation of expression templates. Calling this function explicitly might result
2578 // in erroneous results and/or in compilation errors. Instead of using this function use the
2579 // assignment operator.
2580 */
2581 template< typename MT       // Type of the matrix
2582         , bool SO           // Storage order
2583         , bool DF           // Density flag
2584         , bool SF           // Symmetry flag
2585         , typename... CCAs  // Compile time column arguments
2586         , typename ET >     // Type of the element
tryAdd(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2587 inline bool tryAdd( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2588 {
2589    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2590    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2591 
2592    return tryAdd( c.operand(), c.idx(i), j, value );
2593 }
2594 /*! \endcond */
2595 //*************************************************************************************************
2596 
2597 
2598 //*************************************************************************************************
2599 /*! \cond BLAZE_INTERNAL */
2600 /*!\brief Predict invariant violations by adding to a range of elements of a column selection.
2601 // \ingroup columns
2602 //
2603 // \param c The target column selection.
2604 // \param row The index of the first row of the range to be modified.
2605 // \param column The index of the first column of the range to be modified.
2606 // \param m The number of rows of the range to be modified.
2607 // \param n The number of columns of the range to be modified.
2608 // \param value The value to be added to the range of elements.
2609 // \return \a true in case the operation would be successful, \a false if not.
2610 //
2611 // This function must \b NOT be called explicitly! It is used internally for the performance
2612 // optimized evaluation of expression templates. Calling this function explicitly might result
2613 // in erroneous results and/or in compilation errors. Instead of using this function use the
2614 // assignment operator.
2615 */
2616 template< typename MT       // Type of the matrix
2617         , bool SO           // Storage order
2618         , bool DF           // Density flag
2619         , bool SF           // Symmetry flag
2620         , typename... CCAs  // Compile time column arguments
2621         , typename ET >     // Type of the element
2622 BLAZE_ALWAYS_INLINE bool
tryAdd(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)2623    tryAdd( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
2624 {
2625    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2626    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2627    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2628    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2629 
2630    const size_t jend( column + n );
2631 
2632    for( size_t j=column; j<jend; ++j ) {
2633       if( !tryAdd( c.operand(), row, c.idx(j), m, 1UL, value ) )
2634          return false;
2635    }
2636 
2637    return true;
2638 }
2639 /*! \endcond */
2640 //*************************************************************************************************
2641 
2642 
2643 //*************************************************************************************************
2644 /*! \cond BLAZE_INTERNAL */
2645 /*!\brief Predict invariant violations by subtracting from a single element of a column selection.
2646 // \ingroup columns
2647 //
2648 // \param c The target column selection.
2649 // \param i The row index of the element to be modified.
2650 // \param j The column index of the element to be modified.
2651 // \param value The value to be subtracted from the element.
2652 // \return \a true in case the operation would be successful, \a false if not.
2653 //
2654 // This function must \b NOT be called explicitly! It is used internally for the performance
2655 // optimized evaluation of expression templates. Calling this function explicitly might result
2656 // in erroneous results and/or in compilation errors. Instead of using this function use the
2657 // assignment operator.
2658 */
2659 template< typename MT       // Type of the matrix
2660         , bool SO           // Storage order
2661         , bool DF           // Density flag
2662         , bool SF           // Symmetry flag
2663         , typename... CCAs  // Compile time column arguments
2664         , typename ET >     // Type of the element
trySub(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2665 inline bool trySub( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2666 {
2667    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2668    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2669 
2670    return trySub( c.operand(), c.idx(i), j, value );
2671 }
2672 /*! \endcond */
2673 //*************************************************************************************************
2674 
2675 
2676 //*************************************************************************************************
2677 /*! \cond BLAZE_INTERNAL */
2678 /*!\brief Predict invariant violations by subtracting from a range of elements of a column selection.
2679 // \ingroup columns
2680 //
2681 // \param c The target column selection.
2682 // \param row The index of the first row of the range to be modified.
2683 // \param column The index of the first column of the range to be modified.
2684 // \param m The number of rows of the range to be modified.
2685 // \param n The number of columns of the range to be modified.
2686 // \param value The value to be subtracted to the range of elements.
2687 // \return \a true in case the operation would be successful, \a false if not.
2688 //
2689 // This function must \b NOT be called explicitly! It is used internally for the performance
2690 // optimized evaluation of expression templates. Calling this function explicitly might result
2691 // in erroneous results and/or in compilation errors. Instead of using this function use the
2692 // assignment operator.
2693 */
2694 template< typename MT       // Type of the matrix
2695         , bool SO           // Storage order
2696         , bool DF           // Density flag
2697         , bool SF           // Symmetry flag
2698         , typename... CCAs  // Compile time column arguments
2699         , typename ET >     // Type of the element
2700 BLAZE_ALWAYS_INLINE bool
trySub(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)2701    trySub( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
2702 {
2703    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2704    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2705    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2706    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2707 
2708    const size_t jend( column + n );
2709 
2710    for( size_t j=column; j<jend; ++j ) {
2711       if( !trySub( c.operand(), row, c.idx(j), m, 1UL, value ) )
2712          return false;
2713    }
2714 
2715    return true;
2716 }
2717 /*! \endcond */
2718 //*************************************************************************************************
2719 
2720 
2721 //*************************************************************************************************
2722 /*! \cond BLAZE_INTERNAL */
2723 /*!\brief Predict invariant violations by scaling a single element of a column selection.
2724 // \ingroup columns
2725 //
2726 // \param c The target column selection.
2727 // \param i The row index of the element to be modified.
2728 // \param j The column index of the element to be modified.
2729 // \param value The factor for the element.
2730 // \return \a true in case the operation would be successful, \a false if not.
2731 //
2732 // This function must \b NOT be called explicitly! It is used internally for the performance
2733 // optimized evaluation of expression templates. Calling this function explicitly might result
2734 // in erroneous results and/or in compilation errors. Instead of using this function use the
2735 // assignment operator.
2736 */
2737 template< typename MT       // Type of the matrix
2738         , bool SO           // Storage order
2739         , bool DF           // Density flag
2740         , bool SF           // Symmetry flag
2741         , typename... CCAs  // Compile time column arguments
2742         , typename ET >     // Type of the element
tryMult(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2743 inline bool tryMult( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2744 {
2745    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2746    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2747 
2748    return tryMult( c.operand(), c.idx(i), j, value );
2749 }
2750 /*! \endcond */
2751 //*************************************************************************************************
2752 
2753 
2754 //*************************************************************************************************
2755 /*! \cond BLAZE_INTERNAL */
2756 /*!\brief Predict invariant violations by scaling a range of elements of a column selection.
2757 // \ingroup columns
2758 //
2759 // \param c The target column selection.
2760 // \param row The index of the first row of the range to be modified.
2761 // \param column The index of the first column of the range to be modified.
2762 // \param m The number of rows of the range to be modified.
2763 // \param n The number of columns of the range to be modified.
2764 // \param value The factor for the elements.
2765 // \return \a true in case the operation would be successful, \a false if not.
2766 //
2767 // This function must \b NOT be called explicitly! It is used internally for the performance
2768 // optimized evaluation of expression templates. Calling this function explicitly might result
2769 // in erroneous results and/or in compilation errors. Instead of using this function use the
2770 // assignment operator.
2771 */
2772 template< typename MT       // Type of the matrix
2773         , bool SO           // Storage order
2774         , bool DF           // Density flag
2775         , bool SF           // Symmetry flag
2776         , typename... CCAs  // Compile time column arguments
2777         , typename ET >     // Type of the element
2778 BLAZE_ALWAYS_INLINE bool
tryMult(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)2779    tryMult( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
2780 {
2781    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2782    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2783    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2784    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2785 
2786    const size_t jend( column + n );
2787 
2788    for( size_t j=column; j<jend; ++j ) {
2789       if( !tryMult( c.operand(), row, c.idx(j), m, 1UL, value ) )
2790          return false;
2791    }
2792 
2793    return true;
2794 }
2795 /*! \endcond */
2796 //*************************************************************************************************
2797 
2798 
2799 //*************************************************************************************************
2800 /*! \cond BLAZE_INTERNAL */
2801 /*!\brief Predict invariant violations by scaling a single element of a column selection.
2802 // \ingroup columns
2803 //
2804 // \param c The target column selection.
2805 // \param i The row index of the element to be modified.
2806 // \param j The column index of the element to be modified.
2807 // \param value The divisor for the element.
2808 // \return \a true in case the operation would be successful, \a false if not.
2809 //
2810 // This function must \b NOT be called explicitly! It is used internally for the performance
2811 // optimized evaluation of expression templates. Calling this function explicitly might result
2812 // in erroneous results and/or in compilation errors. Instead of using this function use the
2813 // assignment operator.
2814 */
2815 template< typename MT       // Type of the matrix
2816         , bool SO           // Storage order
2817         , bool DF           // Density flag
2818         , bool SF           // Symmetry flag
2819         , typename... CCAs  // Compile time column arguments
2820         , typename ET >     // Type of the element
tryDiv(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2821 inline bool tryDiv( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2822 {
2823    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2824    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2825 
2826    return tryDiv( c.operand(), c.idx(i), j, value );
2827 }
2828 /*! \endcond */
2829 //*************************************************************************************************
2830 
2831 
2832 //*************************************************************************************************
2833 /*! \cond BLAZE_INTERNAL */
2834 /*!\brief Predict invariant violations by scaling a range of elements of a column selection.
2835 // \ingroup columns
2836 //
2837 // \param c The target column selection.
2838 // \param row The index of the first row of the range to be modified.
2839 // \param column The index of the first column of the range to be modified.
2840 // \param m The number of rows of the range to be modified.
2841 // \param n The number of columns of the range to be modified.
2842 // \param value The divisor for the elements.
2843 // \return \a true in case the operation would be successful, \a false if not.
2844 //
2845 // This function must \b NOT be called explicitly! It is used internally for the performance
2846 // optimized evaluation of expression templates. Calling this function explicitly might result
2847 // in erroneous results and/or in compilation errors. Instead of using this function use the
2848 // assignment operator.
2849 */
2850 template< typename MT       // Type of the matrix
2851         , bool SO           // Storage order
2852         , bool DF           // Density flag
2853         , bool SF           // Symmetry flag
2854         , typename... CCAs  // Compile time column arguments
2855         , typename ET >     // Type of the element
2856 BLAZE_ALWAYS_INLINE bool
tryDiv(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)2857    tryDiv( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
2858 {
2859    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2860    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2861    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2862    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2863 
2864    const size_t jend( column + n );
2865 
2866    for( size_t j=column; j<jend; ++j ) {
2867       if( !tryDiv( c.operand(), row, c.idx(j), m, 1UL, value ) )
2868          return false;
2869    }
2870 
2871    return true;
2872 }
2873 /*! \endcond */
2874 //*************************************************************************************************
2875 
2876 
2877 //*************************************************************************************************
2878 /*! \cond BLAZE_INTERNAL */
2879 /*!\brief Predict invariant violations by shifting a single element of a column selection.
2880 // \ingroup columns
2881 //
2882 // \param c The target column selection.
2883 // \param i The row index of the element to be modified.
2884 // \param j The column index of the element to be modified.
2885 // \param count The number of bits to shift the element.
2886 // \return \a true in case the operation would be successful, \a false if not.
2887 //
2888 // This function must \b NOT be called explicitly! It is used internally for the performance
2889 // optimized evaluation of expression templates. Calling this function explicitly might result
2890 // in erroneous results and/or in compilation errors. Instead of using this function use the
2891 // assignment operator.
2892 */
2893 template< typename MT         // Type of the matrix
2894         , bool SO             // Storage order
2895         , bool DF             // Density flag
2896         , bool SF             // Symmetry flag
2897         , typename... CCAs >  // Compile time column arguments
tryShift(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,int count)2898 inline bool tryShift( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, int count )
2899 {
2900    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2901    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2902 
2903    return tryShift( c.operand(), c.idx(i), j, count );
2904 }
2905 /*! \endcond */
2906 //*************************************************************************************************
2907 
2908 
2909 //*************************************************************************************************
2910 /*! \cond BLAZE_INTERNAL */
2911 /*!\brief Predict invariant violations by shifting a range of elements of a column selection.
2912 // \ingroup columns
2913 //
2914 // \param c The target column selection.
2915 // \param row The index of the first row of the range to be modified.
2916 // \param column The index of the first column of the range to be modified.
2917 // \param m The number of rows of the range to be modified.
2918 // \param n The number of columns of the range to be modified.
2919 // \param count The number of bits to shift the range of elements.
2920 // \return \a true in case the operation would be successful, \a false if not.
2921 //
2922 // This function must \b NOT be called explicitly! It is used internally for the performance
2923 // optimized evaluation of expression templates. Calling this function explicitly might result
2924 // in erroneous results and/or in compilation errors. Instead of using this function use the
2925 // assignment operator.
2926 */
2927 template< typename MT         // Type of the matrix
2928         , bool SO             // Storage order
2929         , bool DF             // Density flag
2930         , bool SF             // Symmetry flag
2931         , typename... CCAs >  // Compile time column arguments
2932 BLAZE_ALWAYS_INLINE bool
tryShift(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,int count)2933    tryShift( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, int count )
2934 {
2935    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
2936    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
2937    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
2938    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
2939 
2940    const size_t jend( column + n );
2941 
2942    for( size_t j=column; j<jend; ++j ) {
2943       if( !tryShift( c.operand(), row, c.idx(j), m, 1UL, count ) )
2944          return false;
2945    }
2946 
2947    return true;
2948 }
2949 /*! \endcond */
2950 //*************************************************************************************************
2951 
2952 
2953 //*************************************************************************************************
2954 /*! \cond BLAZE_INTERNAL */
2955 /*!\brief Predict invariant violations by a bitwise AND on a single element of a column selection.
2956 // \ingroup columns
2957 //
2958 // \param c The target column selection.
2959 // \param i The row index of the element to be modified.
2960 // \param j The column index of the element to be modified.
2961 // \param value The bit pattern to be used on the element.
2962 // \return \a true in case the operation would be successful, \a false if not.
2963 //
2964 // This function must \b NOT be called explicitly! It is used internally for the performance
2965 // optimized evaluation of expression templates. Calling this function explicitly might result
2966 // in erroneous results and/or in compilation errors. Instead of using this function use the
2967 // assignment operator.
2968 */
2969 template< typename MT       // Type of the matrix
2970         , bool SO           // Storage order
2971         , bool DF           // Density flag
2972         , bool SF           // Symmetry flag
2973         , typename... CCAs  // Compile time column arguments
2974         , typename ET >     // Type of the element
tryBitand(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)2975 inline bool tryBitand( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
2976 {
2977    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
2978    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
2979 
2980    return tryBitand( c.operand(), c.idx(i), j, value );
2981 }
2982 /*! \endcond */
2983 //*************************************************************************************************
2984 
2985 
2986 //*************************************************************************************************
2987 /*! \cond BLAZE_INTERNAL */
2988 /*!\brief Predict invariant violations by a bitwise AND on a range of elements of a column selection.
2989 // \ingroup columns
2990 //
2991 // \param c The target column selection.
2992 // \param row The index of the first row of the range to be modified.
2993 // \param column The index of the first column of the range to be modified.
2994 // \param m The number of rows of the range to be modified.
2995 // \param n The number of columns of the range to be modified.
2996 // \param value The bit pattern to be used on the range of elements.
2997 // \return \a true in case the operation would be successful, \a false if not.
2998 //
2999 // This function must \b NOT be called explicitly! It is used internally for the performance
3000 // optimized evaluation of expression templates. Calling this function explicitly might result
3001 // in erroneous results and/or in compilation errors. Instead of using this function use the
3002 // assignment operator.
3003 */
3004 template< typename MT       // Type of the matrix
3005         , bool SO           // Storage order
3006         , bool DF           // Density flag
3007         , bool SF           // Symmetry flag
3008         , typename... CCAs  // Compile time column arguments
3009         , typename ET >     // Type of the element
3010 BLAZE_ALWAYS_INLINE bool
tryBitand(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)3011    tryBitand( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
3012 {
3013    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
3014    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
3015    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
3016    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
3017 
3018    const size_t jend( column + n );
3019 
3020    for( size_t j=column; j<jend; ++j ) {
3021       if( !tryBitand( c.operand(), row, c.idx(j), m, 1UL, value ) )
3022          return false;
3023    }
3024 
3025    return true;
3026 }
3027 /*! \endcond */
3028 //*************************************************************************************************
3029 
3030 
3031 //*************************************************************************************************
3032 /*! \cond BLAZE_INTERNAL */
3033 /*!\brief Predict invariant violations by a bitwise OR on a single element of a column selection.
3034 // \ingroup columns
3035 //
3036 // \param c The target column selection.
3037 // \param i The row index of the element to be modified.
3038 // \param j The column index of the element to be modified.
3039 // \param value The bit pattern to be used on the element.
3040 // \return \a true in case the operation would be successful, \a false if not.
3041 //
3042 // This function must \b NOT be called explicitly! It is used internally for the performance
3043 // optimized evaluation of expression templates. Calling this function explicitly might result
3044 // in erroneous results and/or in compilation errors. Instead of using this function use the
3045 // assignment operator.
3046 */
3047 template< typename MT       // Type of the matrix
3048         , bool SO           // Storage order
3049         , bool DF           // Density flag
3050         , bool SF           // Symmetry flag
3051         , typename... CCAs  // Compile time column arguments
3052         , typename ET >     // Type of the element
tryBitor(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)3053 inline bool tryBitor( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
3054 {
3055    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
3056    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
3057 
3058    return tryBitor( c.operand(), c.idx(i), j, value );
3059 }
3060 /*! \endcond */
3061 //*************************************************************************************************
3062 
3063 
3064 //*************************************************************************************************
3065 /*! \cond BLAZE_INTERNAL */
3066 /*!\brief Predict invariant violations by a bitwise OR on a range of elements of a column selection.
3067 // \ingroup columns
3068 //
3069 // \param c The target column selection.
3070 // \param row The index of the first row of the range to be modified.
3071 // \param column The index of the first column of the range to be modified.
3072 // \param m The number of rows of the range to be modified.
3073 // \param n The number of columns of the range to be modified.
3074 // \param value The bit pattern to be used on the range of elements.
3075 // \return \a true in case the operation would be successful, \a false if not.
3076 //
3077 // This function must \b NOT be called explicitly! It is used internally for the performance
3078 // optimized evaluation of expression templates. Calling this function explicitly might result
3079 // in erroneous results and/or in compilation errors. Instead of using this function use the
3080 // assignment operator.
3081 */
3082 template< typename MT       // Type of the matrix
3083         , bool SO           // Storage order
3084         , bool DF           // Density flag
3085         , bool SF           // Symmetry flag
3086         , typename... CCAs  // Compile time column arguments
3087         , typename ET >     // Type of the element
3088 BLAZE_ALWAYS_INLINE bool
tryBitor(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)3089    tryBitor( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
3090 {
3091    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
3092    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
3093    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
3094    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
3095 
3096    const size_t jend( column + n );
3097 
3098    for( size_t j=column; j<jend; ++j ) {
3099       if( !tryBitor( c.operand(), row, c.idx(j), m, 1UL, value ) )
3100          return false;
3101    }
3102 
3103    return true;
3104 }
3105 /*! \endcond */
3106 //*************************************************************************************************
3107 
3108 
3109 //*************************************************************************************************
3110 /*! \cond BLAZE_INTERNAL */
3111 /*!\brief Predict invariant violations by a bitwise XOR on a single element of a column selection.
3112 // \ingroup columns
3113 //
3114 // \param c The target column selection.
3115 // \param i The row index of the element to be modified.
3116 // \param j The column index of the element to be modified.
3117 // \param value The bit pattern to be used on the element.
3118 // \return \a true in case the operation would be successful, \a false if not.
3119 //
3120 // This function must \b NOT be called explicitly! It is used internally for the performance
3121 // optimized evaluation of expression templates. Calling this function explicitly might result
3122 // in erroneous results and/or in compilation errors. Instead of using this function use the
3123 // assignment operator.
3124 */
3125 template< typename MT       // Type of the matrix
3126         , bool SO           // Storage order
3127         , bool DF           // Density flag
3128         , bool SF           // Symmetry flag
3129         , typename... CCAs  // Compile time column arguments
3130         , typename ET >     // Type of the element
tryBitxor(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t i,size_t j,const ET & value)3131 inline bool tryBitxor( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t i, size_t j, const ET& value )
3132 {
3133    BLAZE_INTERNAL_ASSERT( i < c.rows(), "Invalid row access index" );
3134    BLAZE_INTERNAL_ASSERT( j < c.columns(), "Invalid column access index" );
3135 
3136    return tryBitxor( c.operand(), c.idx(i), j, value );
3137 }
3138 /*! \endcond */
3139 //*************************************************************************************************
3140 
3141 
3142 //*************************************************************************************************
3143 /*! \cond BLAZE_INTERNAL */
3144 /*!\brief Predict invariant violations by a bitwise XOR on a range of elements of a column selection.
3145 // \ingroup columns
3146 //
3147 // \param c The target column selection.
3148 // \param row The index of the first row of the range to be modified.
3149 // \param column The index of the first column of the range to be modified.
3150 // \param m The number of rows of the range to be modified.
3151 // \param n The number of columns of the range to be modified.
3152 // \param value The bit pattern to be used on the range of elements.
3153 // \return \a true in case the operation would be successful, \a false if not.
3154 //
3155 // This function must \b NOT be called explicitly! It is used internally for the performance
3156 // optimized evaluation of expression templates. Calling this function explicitly might result
3157 // in erroneous results and/or in compilation errors. Instead of using this function use the
3158 // assignment operator.
3159 */
3160 template< typename MT       // Type of the matrix
3161         , bool SO           // Storage order
3162         , bool DF           // Density flag
3163         , bool SF           // Symmetry flag
3164         , typename... CCAs  // Compile time column arguments
3165         , typename ET >     // Type of the element
3166 BLAZE_ALWAYS_INLINE bool
tryBitxor(const Columns<MT,SO,DF,SF,CCAs...> & c,size_t row,size_t column,size_t m,size_t n,const ET & value)3167    tryBitxor( const Columns<MT,SO,DF,SF,CCAs...>& c, size_t row, size_t column, size_t m, size_t n, const ET& value )
3168 {
3169    BLAZE_INTERNAL_ASSERT( row <= (*c).rows(), "Invalid row access index" );
3170    BLAZE_INTERNAL_ASSERT( column <= (*c).columns(), "Invalid column access index" );
3171    BLAZE_INTERNAL_ASSERT( row + m <= (*c).rows(), "Invalid number of rows" );
3172    BLAZE_INTERNAL_ASSERT( column + n <= (*c).columns(), "Invalid number of columns" );
3173 
3174    const size_t jend( column + n );
3175 
3176    for( size_t j=column; j<jend; ++j ) {
3177       if( !tryBitxor( c.operand(), row, c.idx(j), m, 1UL, value ) )
3178          return false;
3179    }
3180 
3181    return true;
3182 }
3183 /*! \endcond */
3184 //*************************************************************************************************
3185 
3186 
3187 //*************************************************************************************************
3188 /*! \cond BLAZE_INTERNAL */
3189 /*!\brief Predict invariant violations by the assignment of a column vector to a column selection.
3190 // \ingroup columns
3191 //
3192 // \param lhs The target left-hand side column selection.
3193 // \param rhs The right-hand side column vector to be assigned.
3194 // \param row The row index of the first element to be modified.
3195 // \param column The column index of the first element to be modified.
3196 // \return \a true in case the assignment would be successful, \a false if not.
3197 //
3198 // This function must \b NOT be called explicitly! It is used internally for the performance
3199 // optimized evaluation of expression templates. Calling this function explicitly might result
3200 // in erroneous results and/or in compilation errors. Instead of using this function use the
3201 // assignment operator.
3202 */
3203 template< typename MT       // Type of the matrix
3204         , bool SO           // Storage order
3205         , bool DF           // Density flag
3206         , bool SF           // Symmetry flag
3207         , typename... CCAs  // Compile time column arguments
3208         , typename VT >     // Type of the right-hand side vector
tryAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3209 inline bool tryAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3210                        const Vector<VT,false>& rhs, size_t row, size_t column )
3211 {
3212    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3213    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3214    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3215 
3216    return tryAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
3217 }
3218 /*! \endcond */
3219 //*************************************************************************************************
3220 
3221 
3222 //*************************************************************************************************
3223 /*! \cond BLAZE_INTERNAL */
3224 /*!\brief Predict invariant violations by the assignment of a row vector to a column selection.
3225 // \ingroup columns
3226 //
3227 // \param lhs The target left-hand side column selection.
3228 // \param rhs The right-hand side row vector to be assigned.
3229 // \param row The row index of the first element to be modified.
3230 // \param column The column index of the first element to be modified.
3231 // \return \a true in case the assignment would be successful, \a false if not.
3232 //
3233 // This function must \b NOT be called explicitly! It is used internally for the performance
3234 // optimized evaluation of expression templates. Calling this function explicitly might result
3235 // in erroneous results and/or in compilation errors. Instead of using this function use the
3236 // assignment operator.
3237 */
3238 template< typename MT       // Type of the matrix
3239         , bool SO           // Storage order
3240         , bool DF           // Density flag
3241         , bool SF           // Symmetry flag
3242         , typename... CCAs  // Compile time column arguments
3243         , typename VT >     // Type of the right-hand side vector
tryAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)3244 inline bool tryAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3245                        const Vector<VT,true>& rhs, size_t row, size_t column )
3246 {
3247    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3248    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3249    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3250 
3251    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3252       if( !trySet( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
3253          return false;
3254    }
3255 
3256    return true;
3257 }
3258 /*! \endcond */
3259 //*************************************************************************************************
3260 
3261 
3262 //*************************************************************************************************
3263 /*! \cond BLAZE_INTERNAL */
3264 /*!\brief Predict invariant violations by the assignment of a vector to the band of a column
3265 //        selection.
3266 // \ingroup columns
3267 //
3268 // \param lhs The target left-hand side column selection.
3269 // \param rhs The right-hand side vector to be assigned.
3270 // \param band The index of the band the right-hand side vector is assigned to.
3271 // \param row The row index of the first element to be modified.
3272 // \param column The column index of the first element to be modified.
3273 // \return \a true in case the assignment would be successful, \a false if not.
3274 //
3275 // This function must \b NOT be called explicitly! It is used internally for the performance
3276 // optimized evaluation of expression templates. Calling this function explicitly might result
3277 // in erroneous results and/or in compilation errors. Instead of using this function use the
3278 // assignment operator.
3279 */
3280 template< typename MT       // Type of the matrix
3281         , bool SO           // Storage order
3282         , bool DF           // Density flag
3283         , bool SF           // Symmetry flag
3284         , typename... CCAs  // Compile time column arguments
3285         , typename VT       // Type of the right-hand side vector
3286         , bool TF >         // Transpose flag of the right-hand side vector
tryAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)3287 inline bool tryAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3288                        const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
3289 {
3290    MAYBE_UNUSED( band );
3291 
3292    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3293    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3294    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3295    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3296 
3297    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3298       if( !trySet( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
3299          return false;
3300    }
3301 
3302    return true;
3303 }
3304 /*! \endcond */
3305 //*************************************************************************************************
3306 
3307 
3308 //*************************************************************************************************
3309 /*! \cond BLAZE_INTERNAL */
3310 /*!\brief Predict invariant violations by the assignment of a matrix to a column selection.
3311 // \ingroup columns
3312 //
3313 // \param lhs The target left-hand side column selection.
3314 // \param rhs The right-hand side matrix to be assigned.
3315 // \param row The row index of the first element to be modified.
3316 // \param column The column index of the first element to be modified.
3317 // \return \a true in case the assignment would be successful, \a false if not.
3318 //
3319 // This function must \b NOT be called explicitly! It is used internally for the performance
3320 // optimized evaluation of expression templates. Calling this function explicitly might result
3321 // in erroneous results and/or in compilation errors. Instead of using this function use the
3322 // assignment operator.
3323 */
3324 template< typename MT1      // Type of the matrix
3325         , bool SO1          // Storage order
3326         , bool DF           // Density flag
3327         , bool SF           // Symmetry flag
3328         , typename... CCAs  // Compile time column arguments
3329         , typename MT2      // Type of the right-hand side matrix
3330         , bool SO2 >        // Storage order of the right-hand side matrix
tryAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)3331 inline bool tryAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
3332                        const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
3333 {
3334    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3335    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3336    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
3337    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
3338 
3339    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
3340       if( !tryAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
3341          return false;
3342    }
3343 
3344    return true;
3345 }
3346 /*! \endcond */
3347 //*************************************************************************************************
3348 
3349 
3350 //*************************************************************************************************
3351 /*! \cond BLAZE_INTERNAL */
3352 /*!\brief Predict invariant violations by the addition assignment of a column vector to a column
3353 //        selection.
3354 // \ingroup columns
3355 //
3356 // \param lhs The target left-hand side column selection.
3357 // \param rhs The right-hand side column vector to be added.
3358 // \param row The row index of the first element to be modified.
3359 // \param column The column index of the first element to be modified.
3360 // \return \a true in case the assignment would be successful, \a false if not.
3361 //
3362 // This function must \b NOT be called explicitly! It is used internally for the performance
3363 // optimized evaluation of expression templates. Calling this function explicitly might result
3364 // in erroneous results and/or in compilation errors. Instead of using this function use the
3365 // assignment operator.
3366 */
3367 template< typename MT       // Type of the matrix
3368         , bool SO           // Storage order
3369         , bool DF           // Density flag
3370         , bool SF           // Symmetry flag
3371         , typename... CCAs  // Compile time column arguments
3372         , typename VT >     // Type of the right-hand side vector
tryAddAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3373 inline bool tryAddAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3374                           const Vector<VT,false>& rhs, size_t row, size_t column )
3375 {
3376    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3377    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3378    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3379 
3380    return tryAddAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
3381 }
3382 /*! \endcond */
3383 //*************************************************************************************************
3384 
3385 
3386 //*************************************************************************************************
3387 /*! \cond BLAZE_INTERNAL */
3388 /*!\brief Predict invariant violations by the addition assignment of a row vector to a column
3389 //        selection.
3390 // \ingroup columns
3391 //
3392 // \param lhs The target left-hand side column selection.
3393 // \param rhs The right-hand side row vector to be added.
3394 // \param row The row index of the first element to be modified.
3395 // \param column The column index of the first element to be modified.
3396 // \return \a true in case the assignment would be successful, \a false if not.
3397 //
3398 // This function must \b NOT be called explicitly! It is used internally for the performance
3399 // optimized evaluation of expression templates. Calling this function explicitly might result
3400 // in erroneous results and/or in compilation errors. Instead of using this function use the
3401 // assignment operator.
3402 */
3403 template< typename MT       // Type of the matrix
3404         , bool SO           // Storage order
3405         , bool DF           // Density flag
3406         , bool SF           // Symmetry flag
3407         , typename... CCAs  // Compile time column arguments
3408         , typename VT >     // Type of the right-hand side vector
tryAddAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)3409 inline bool tryAddAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3410                           const Vector<VT,true>& rhs, size_t row, size_t column )
3411 {
3412    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3413    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3414    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3415 
3416    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3417       if( !tryAdd( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
3418          return false;
3419    }
3420 
3421    return true;
3422 }
3423 /*! \endcond */
3424 //*************************************************************************************************
3425 
3426 
3427 //*************************************************************************************************
3428 /*! \cond BLAZE_INTERNAL */
3429 /*!\brief Predict invariant violations by the addition assignment of a vector to the band of a
3430 //        column selection.
3431 // \ingroup columns
3432 //
3433 // \param lhs The target left-hand side column selection.
3434 // \param rhs The right-hand side vector to be added.
3435 // \param band The index of the band the right-hand side vector is assigned to.
3436 // \param row The row index of the first element to be modified.
3437 // \param column The column index of the first element to be modified.
3438 // \return \a true in case the assignment would be successful, \a false if not.
3439 //
3440 // This function must \b NOT be called explicitly! It is used internally for the performance
3441 // optimized evaluation of expression templates. Calling this function explicitly might result
3442 // in erroneous results and/or in compilation errors. Instead of using this function use the
3443 // assignment operator.
3444 */
3445 template< typename MT       // Type of the matrix
3446         , bool SO           // Storage order
3447         , bool DF           // Density flag
3448         , bool SF           // Symmetry flag
3449         , typename... CCAs  // Compile time column arguments
3450         , typename VT       // Type of the right-hand side vector
3451         , bool TF >         // Transpose flag of the right-hand side vector
tryAddAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)3452 inline bool tryAddAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3453                           const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
3454 {
3455    MAYBE_UNUSED( band );
3456 
3457    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3458    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3459    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3460    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3461 
3462    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3463       if( !tryAdd( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
3464          return false;
3465    }
3466 
3467    return true;
3468 }
3469 /*! \endcond */
3470 //*************************************************************************************************
3471 
3472 
3473 //*************************************************************************************************
3474 /*! \cond BLAZE_INTERNAL */
3475 /*!\brief Predict invariant violations by the addition assignment of a matrix to a column selection.
3476 // \ingroup columns
3477 //
3478 // \param lhs The target left-hand side column selection.
3479 // \param rhs The right-hand side matrix to be added.
3480 // \param row The row index of the first element to be modified.
3481 // \param column The column index of the first element to be modified.
3482 // \return \a true in case the assignment would be successful, \a false if not.
3483 //
3484 // This function must \b NOT be called explicitly! It is used internally for the performance
3485 // optimized evaluation of expression templates. Calling this function explicitly might result
3486 // in erroneous results and/or in compilation errors. Instead of using this function use the
3487 // assignment operator.
3488 */
3489 template< typename MT1      // Type of the matrix
3490         , bool SO1          // Storage order
3491         , bool DF           // Density flag
3492         , bool SF           // Symmetry flag
3493         , typename... CCAs  // Compile time column arguments
3494         , typename MT2      // Type of the right-hand side matrix
3495         , bool SO2 >        // Storage order of the right-hand side matrix
tryAddAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)3496 inline bool tryAddAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
3497                           const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
3498 {
3499    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3500    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3501    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
3502    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
3503 
3504    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
3505       if( !tryAddAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
3506          return false;
3507    }
3508 
3509    return true;
3510 }
3511 /*! \endcond */
3512 //*************************************************************************************************
3513 
3514 
3515 //*************************************************************************************************
3516 /*! \cond BLAZE_INTERNAL */
3517 /*!\brief Predict invariant violations by the subtraction assignment of a column vector to a
3518 //        column selection.
3519 // \ingroup columns
3520 //
3521 // \param lhs The target left-hand side column selection.
3522 // \param rhs The right-hand side column vector to be subtracted.
3523 // \param row The row index of the first element to be modified.
3524 // \param column The column index of the first element to be modified.
3525 // \return \a true in case the assignment would be successful, \a false if not.
3526 //
3527 // This function must \b NOT be called explicitly! It is used internally for the performance
3528 // optimized evaluation of expression templates. Calling this function explicitly might result
3529 // in erroneous results and/or in compilation errors. Instead of using this function use the
3530 // assignment operator.
3531 */
3532 template< typename MT       // Type of the matrix
3533         , bool SO           // Storage order
3534         , bool DF           // Density flag
3535         , bool SF           // Symmetry flag
3536         , typename... CCAs  // Compile time column arguments
3537         , typename VT >     // Type of the right-hand side vector
trySubAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3538 inline bool trySubAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3539                           const Vector<VT,false>& rhs, size_t row, size_t column )
3540 {
3541    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3542    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3543    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3544 
3545    return trySubAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
3546 }
3547 /*! \endcond */
3548 //*************************************************************************************************
3549 
3550 
3551 //*************************************************************************************************
3552 /*! \cond BLAZE_INTERNAL */
3553 /*!\brief Predict invariant violations by the subtraction assignment of a row vector to a column
3554 //        selection.
3555 // \ingroup columns
3556 //
3557 // \param lhs The target left-hand side column selection.
3558 // \param rhs The right-hand side row vector to be subtracted.
3559 // \param row The row index of the first element to be modified.
3560 // \param column The column index of the first element to be modified.
3561 // \return \a true in case the assignment would be successful, \a false if not.
3562 //
3563 // This function must \b NOT be called explicitly! It is used internally for the performance
3564 // optimized evaluation of expression templates. Calling this function explicitly might result
3565 // in erroneous results and/or in compilation errors. Instead of using this function use the
3566 // assignment operator.
3567 */
3568 template< typename MT       // Type of the matrix
3569         , bool SO           // Storage order
3570         , bool DF           // Density flag
3571         , bool SF           // Symmetry flag
3572         , typename... CCAs  // Compile time column arguments
3573         , typename VT >     // Type of the right-hand side vector
trySubAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)3574 inline bool trySubAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3575                           const Vector<VT,true>& rhs, size_t row, size_t column )
3576 {
3577    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3578    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3579    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3580 
3581    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3582       if( !trySub( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
3583          return false;
3584    }
3585 
3586    return true;
3587 }
3588 /*! \endcond */
3589 //*************************************************************************************************
3590 
3591 
3592 //*************************************************************************************************
3593 /*! \cond BLAZE_INTERNAL */
3594 /*!\brief Predict invariant violations by the subtraction assignment of a vector to the band of a
3595 //        column selection.
3596 // \ingroup columns
3597 //
3598 // \param lhs The target left-hand side column selection.
3599 // \param rhs The right-hand side vector to be subtracted.
3600 // \param band The index of the band the right-hand side vector is assigned to.
3601 // \param row The row index of the first element to be modified.
3602 // \param column The column index of the first element to be modified.
3603 // \return \a true in case the assignment would be successful, \a false if not.
3604 //
3605 // This function must \b NOT be called explicitly! It is used internally for the performance
3606 // optimized evaluation of expression templates. Calling this function explicitly might result
3607 // in erroneous results and/or in compilation errors. Instead of using this function use the
3608 // assignment operator.
3609 */
3610 template< typename MT       // Type of the matrix
3611         , bool SO           // Storage order
3612         , bool DF           // Density flag
3613         , bool SF           // Symmetry flag
3614         , typename... CCAs  // Compile time column arguments
3615         , typename VT       // Type of the right-hand side vector
3616         , bool TF >         // Transpose flag of the right-hand side vector
trySubAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)3617 inline bool trySubAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3618                           const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
3619 {
3620    MAYBE_UNUSED( band );
3621 
3622    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3623    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3624    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3625    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3626 
3627    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3628       if( !trySub( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
3629          return false;
3630    }
3631 
3632    return true;
3633 }
3634 /*! \endcond */
3635 //*************************************************************************************************
3636 
3637 
3638 //*************************************************************************************************
3639 /*! \cond BLAZE_INTERNAL */
3640 /*!\brief Predict invariant violations by the subtraction assignment of a matrix to a column
3641 //        selection.
3642 // \ingroup columns
3643 //
3644 // \param lhs The target left-hand side column selection.
3645 // \param rhs The right-hand side matrix to be subtracted.
3646 // \param row The row index of the first element to be modified.
3647 // \param column The column index of the first element to be modified.
3648 // \return \a true in case the assignment would be successful, \a false if not.
3649 //
3650 // This function must \b NOT be called explicitly! It is used internally for the performance
3651 // optimized evaluation of expression templates. Calling this function explicitly might result
3652 // in erroneous results and/or in compilation errors. Instead of using this function use the
3653 // assignment operator.
3654 */
3655 template< typename MT1      // Type of the matrix
3656         , bool SO1          // Storage order
3657         , bool DF           // Density flag
3658         , bool SF           // Symmetry flag
3659         , typename... CCAs  // Compile time column arguments
3660         , typename MT2      // Type of the right-hand side matrix
3661         , bool SO2 >        // Storage order of the right-hand side matrix
trySubAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)3662 inline bool trySubAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
3663                           const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
3664 {
3665    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3666    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3667    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
3668    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
3669 
3670    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
3671       if( !trySubAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
3672          return false;
3673    }
3674 
3675    return true;
3676 }
3677 /*! \endcond */
3678 //*************************************************************************************************
3679 
3680 
3681 //*************************************************************************************************
3682 /*! \cond BLAZE_INTERNAL */
3683 /*!\brief Predict invariant violations by the multiplication assignment of a column vector to a
3684 //        column selection.
3685 // \ingroup columns
3686 //
3687 // \param lhs The target left-hand side column selection.
3688 // \param rhs The right-hand side column vector to be multiplied.
3689 // \param row The row index of the first element to be modified.
3690 // \param column The column index of the first element to be modified.
3691 // \return \a true in case the assignment would be successful, \a false if not.
3692 //
3693 // This function must \b NOT be called explicitly! It is used internally for the performance
3694 // optimized evaluation of expression templates. Calling this function explicitly might result
3695 // in erroneous results and/or in compilation errors. Instead of using this function use the
3696 // assignment operator.
3697 */
3698 template< typename MT       // Type of the matrix
3699         , bool SO           // Storage order
3700         , bool DF           // Density flag
3701         , bool SF           // Symmetry flag
3702         , typename... CCAs  // Compile time column arguments
3703         , typename VT >     // Type of the right-hand side vector
tryMultAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3704 inline bool tryMultAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3705                            const Vector<VT,false>& rhs, size_t row, size_t column )
3706 {
3707    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3708    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3709    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3710 
3711    return tryMultAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
3712 }
3713 /*! \endcond */
3714 //*************************************************************************************************
3715 
3716 
3717 //*************************************************************************************************
3718 /*! \cond BLAZE_INTERNAL */
3719 /*!\brief Predict invariant violations by the multiplication assignment of a row vector to a
3720 //        column selection.
3721 // \ingroup columns
3722 //
3723 // \param lhs The target left-hand side column selection.
3724 // \param rhs The right-hand side row vector to be multiplied.
3725 // \param row The row index of the first element to be modified.
3726 // \param column The column index of the first element to be modified.
3727 // \return \a true in case the assignment would be successful, \a false if not.
3728 //
3729 // This function must \b NOT be called explicitly! It is used internally for the performance
3730 // optimized evaluation of expression templates. Calling this function explicitly might result
3731 // in erroneous results and/or in compilation errors. Instead of using this function use the
3732 // assignment operator.
3733 */
3734 template< typename MT       // Type of the matrix
3735         , bool SO           // Storage order
3736         , bool DF           // Density flag
3737         , bool SF           // Symmetry flag
3738         , typename... CCAs  // Compile time column arguments
3739         , typename VT >     // Type of the right-hand side vector
tryMultAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)3740 inline bool tryMultAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3741                            const Vector<VT,true>& rhs, size_t row, size_t column )
3742 {
3743    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3744    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3745    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3746 
3747    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3748       if( !tryMult( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
3749          return false;
3750    }
3751 
3752    return true;
3753 }
3754 /*! \endcond */
3755 //*************************************************************************************************
3756 
3757 
3758 //*************************************************************************************************
3759 /*! \cond BLAZE_INTERNAL */
3760 /*!\brief Predict invariant violations by the multiplication assignment of a vector to the band
3761 //        of a column selection.
3762 // \ingroup columns
3763 //
3764 // \param lhs The target left-hand side column selection.
3765 // \param rhs The right-hand side vector to be multiplied.
3766 // \param band The index of the band the right-hand side vector is assigned to.
3767 // \param row The row index of the first element to be modified.
3768 // \param column The column index of the first element to be modified.
3769 // \return \a true in case the assignment would be successful, \a false if not.
3770 //
3771 // This function must \b NOT be called explicitly! It is used internally for the performance
3772 // optimized evaluation of expression templates. Calling this function explicitly might result
3773 // in erroneous results and/or in compilation errors. Instead of using this function use the
3774 // assignment operator.
3775 */
3776 template< typename MT       // Type of the matrix
3777         , bool SO           // Storage order
3778         , bool DF           // Density flag
3779         , bool SF           // Symmetry flag
3780         , typename... CCAs  // Compile time column arguments
3781         , typename VT       // Type of the right-hand side vector
3782         , bool TF >         // Transpose flag of the right-hand side vector
tryMultAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)3783 inline bool tryMultAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3784                            const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
3785 {
3786    MAYBE_UNUSED( band );
3787 
3788    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3789    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3790    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3791    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3792 
3793    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3794       if( !tryMult( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
3795          return false;
3796    }
3797 
3798    return true;
3799 }
3800 /*! \endcond */
3801 //*************************************************************************************************
3802 
3803 
3804 //*************************************************************************************************
3805 /*! \cond BLAZE_INTERNAL */
3806 /*!\brief Predict invariant violations by the Schur product assignment of a matrix to a column
3807 //        selection.
3808 // \ingroup columns
3809 //
3810 // \param lhs The target left-hand side column selection.
3811 // \param rhs The right-hand side matrix for the Schur product.
3812 // \param row The row index of the first element to be modified.
3813 // \param column The column index of the first element to be modified.
3814 // \return \a true in case the assignment would be successful, \a false if not.
3815 //
3816 // This function must \b NOT be called explicitly! It is used internally for the performance
3817 // optimized evaluation of expression templates. Calling this function explicitly might result
3818 // in erroneous results and/or in compilation errors. Instead of using this function use the
3819 // assignment operator.
3820 */
3821 template< typename MT1      // Type of the matrix
3822         , bool SO1          // Storage order
3823         , bool DF           // Density flag
3824         , bool SF           // Symmetry flag
3825         , typename... CCAs  // Compile time column arguments
3826         , typename MT2      // Type of the right-hand side matrix
3827         , bool SO2 >        // Storage order of the right-hand side matrix
trySchurAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)3828 inline bool trySchurAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
3829                             const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
3830 {
3831    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3832    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3833    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
3834    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
3835 
3836    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
3837       if( !tryMultAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
3838          return false;
3839    }
3840 
3841    return true;
3842 }
3843 /*! \endcond */
3844 //*************************************************************************************************
3845 
3846 
3847 //*************************************************************************************************
3848 /*! \cond BLAZE_INTERNAL */
3849 /*!\brief Predict invariant violations by the division assignment of a column vector to a column
3850 //        selection.
3851 // \ingroup columns
3852 //
3853 // \param lhs The target left-hand side column selection.
3854 // \param rhs The right-hand side column vector divisor.
3855 // \param row The row index of the first element to be modified.
3856 // \param column The column index of the first element to be modified.
3857 // \return \a true in case the assignment would be successful, \a false if not.
3858 //
3859 // This function must \b NOT be called explicitly! It is used internally for the performance
3860 // optimized evaluation of expression templates. Calling this function explicitly might result
3861 // in erroneous results and/or in compilation errors. Instead of using this function use the
3862 // assignment operator.
3863 */
3864 template< typename MT       // Type of the matrix
3865         , bool SO           // Storage order
3866         , bool DF           // Density flag
3867         , bool SF           // Symmetry flag
3868         , typename... CCAs  // Compile time column arguments
3869         , typename VT >     // Type of the right-hand side vector
tryDivAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3870 inline bool tryDivAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3871                           const Vector<VT,false>& rhs, size_t row, size_t column )
3872 {
3873    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3874    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3875    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3876 
3877    return tryDivAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
3878 }
3879 /*! \endcond */
3880 //*************************************************************************************************
3881 
3882 
3883 //*************************************************************************************************
3884 /*! \cond BLAZE_INTERNAL */
3885 /*!\brief Predict invariant violations by the division assignment of a row vector to a column
3886 //        selection.
3887 // \ingroup columns
3888 //
3889 // \param lhs The target left-hand side column selection.
3890 // \param rhs The right-hand side row vector divisor.
3891 // \param row The row index of the first element to be modified.
3892 // \param column The column index of the first element to be modified.
3893 // \return \a true in case the assignment would be successful, \a false if not.
3894 //
3895 // This function must \b NOT be called explicitly! It is used internally for the performance
3896 // optimized evaluation of expression templates. Calling this function explicitly might result
3897 // in erroneous results and/or in compilation errors. Instead of using this function use the
3898 // assignment operator.
3899 */
3900 template< typename MT       // Type of the matrix
3901         , bool SO           // Storage order
3902         , bool DF           // Density flag
3903         , bool SF           // Symmetry flag
3904         , typename... CCAs  // Compile time column arguments
3905         , typename VT >     // Type of the right-hand side vector
tryDivAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)3906 inline bool tryDivAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3907                           const Vector<VT,true>& rhs, size_t row, size_t column )
3908 {
3909    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3910    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3911    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3912 
3913    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3914       if( !tryDiv( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
3915          return false;
3916    }
3917 
3918    return true;
3919 }
3920 /*! \endcond */
3921 //*************************************************************************************************
3922 
3923 
3924 //*************************************************************************************************
3925 /*! \cond BLAZE_INTERNAL */
3926 /*!\brief Predict invariant violations by the division assignment of a vector to the band of a
3927 //        column selection.
3928 // \ingroup columns
3929 //
3930 // \param lhs The target left-hand side column selection.
3931 // \param rhs The right-hand side vector divisor.
3932 // \param band The index of the band the right-hand side vector is assigned to.
3933 // \param row The row index of the first element to be modified.
3934 // \param column The column index of the first element to be modified.
3935 // \return \a true in case the assignment would be successful, \a false if not.
3936 //
3937 // This function must \b NOT be called explicitly! It is used internally for the performance
3938 // optimized evaluation of expression templates. Calling this function explicitly might result
3939 // in erroneous results and/or in compilation errors. Instead of using this function use the
3940 // assignment operator.
3941 */
3942 template< typename MT       // Type of the matrix
3943         , bool SO           // Storage order
3944         , bool DF           // Density flag
3945         , bool SF           // Symmetry flag
3946         , typename... CCAs  // Compile time column arguments
3947         , typename VT       // Type of the right-hand side vector
3948         , bool TF >         // Transpose flag of the right-hand side vector
tryDivAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)3949 inline bool tryDivAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3950                           const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
3951 {
3952    MAYBE_UNUSED( band );
3953 
3954    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3955    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3956    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3957    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
3958 
3959    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
3960       if( !tryDiv( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
3961          return false;
3962    }
3963 
3964    return true;
3965 }
3966 /*! \endcond */
3967 //*************************************************************************************************
3968 
3969 
3970 //*************************************************************************************************
3971 /*! \cond BLAZE_INTERNAL */
3972 /*!\brief Predict invariant violations by the shift assignment of a column vector to a column
3973 //        selection.
3974 // \ingroup columns
3975 //
3976 // \param lhs The target left-hand side column selection.
3977 // \param rhs The right-hand side column vector of bits to shift.
3978 // \param row The row index of the first element to be modified.
3979 // \param column The column index of the first element to be modified.
3980 // \return \a true in case the assignment would be successful, \a false if not.
3981 //
3982 // This function must \b NOT be called explicitly! It is used internally for the performance
3983 // optimized evaluation of expression templates. Calling this function explicitly might result
3984 // in erroneous results and/or in compilation errors. Instead of using this function use the
3985 // assignment operator.
3986 */
3987 template< typename MT       // Type of the matrix
3988         , bool SO           // Storage order
3989         , bool DF           // Density flag
3990         , bool SF           // Symmetry flag
3991         , typename... CCAs  // Compile time column arguments
3992         , typename VT >     // Type of the right-hand side vector
tryShiftAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)3993 inline bool tryShiftAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
3994                             const Vector<VT,false>& rhs, size_t row, size_t column )
3995 {
3996    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
3997    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
3998    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
3999 
4000    return tryShiftAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
4001 }
4002 /*! \endcond */
4003 //*************************************************************************************************
4004 
4005 
4006 //*************************************************************************************************
4007 /*! \cond BLAZE_INTERNAL */
4008 /*!\brief Predict invariant violations by the shift assignment of a row vector to a column
4009 //        selection.
4010 // \ingroup columns
4011 //
4012 // \param lhs The target left-hand side column selection.
4013 // \param rhs The right-hand side row vector of bits to shift.
4014 // \param row The row index of the first element to be modified.
4015 // \param column The column index of the first element to be modified.
4016 // \return \a true in case the assignment would be successful, \a false if not.
4017 //
4018 // This function must \b NOT be called explicitly! It is used internally for the performance
4019 // optimized evaluation of expression templates. Calling this function explicitly might result
4020 // in erroneous results and/or in compilation errors. Instead of using this function use the
4021 // assignment operator.
4022 */
4023 template< typename MT       // Type of the matrix
4024         , bool SO           // Storage order
4025         , bool DF           // Density flag
4026         , bool SF           // Symmetry flag
4027         , typename... CCAs  // Compile time column arguments
4028         , typename VT >     // Type of the right-hand side vector
tryShiftAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)4029 inline bool tryShiftAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4030                             const Vector<VT,true>& rhs, size_t row, size_t column )
4031 {
4032    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4033    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4034    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4035 
4036    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4037       if( !tryShift( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
4038          return false;
4039    }
4040 
4041    return true;
4042 }
4043 /*! \endcond */
4044 //*************************************************************************************************
4045 
4046 
4047 //*************************************************************************************************
4048 /*! \cond BLAZE_INTERNAL */
4049 /*!\brief Predict invariant violations by the shift assignment of a vector to the band of a
4050 //        column selection.
4051 // \ingroup columns
4052 //
4053 // \param lhs The target left-hand side column selection.
4054 // \param rhs The right-hand side vector of bits to shift.
4055 // \param band The index of the band the right-hand side vector is assigned to.
4056 // \param row The row index of the first element to be modified.
4057 // \param column The column index of the first element to be modified.
4058 // \return \a true in case the assignment would be successful, \a false if not.
4059 //
4060 // This function must \b NOT be called explicitly! It is used internally for the performance
4061 // optimized evaluation of expression templates. Calling this function explicitly might result
4062 // in erroneous results and/or in compilation errors. Instead of using this function use the
4063 // assignment operator.
4064 */
4065 template< typename MT       // Type of the matrix
4066         , bool SO           // Storage order
4067         , bool DF           // Density flag
4068         , bool SF           // Symmetry flag
4069         , typename... CCAs  // Compile time column arguments
4070         , typename VT       // Type of the right-hand side vector
4071         , bool TF >         // Transpose flag of the right-hand side vector
tryShiftAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)4072 inline bool tryShiftAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4073                             const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4074 {
4075    MAYBE_UNUSED( band );
4076 
4077    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4078    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4079    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4080    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4081 
4082    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4083       if( !tryShift( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
4084          return false;
4085    }
4086 
4087    return true;
4088 }
4089 /*! \endcond */
4090 //*************************************************************************************************
4091 
4092 
4093 //*************************************************************************************************
4094 /*! \cond BLAZE_INTERNAL */
4095 /*!\brief Predict invariant violations by the shift assignment of a matrix to a column selection.
4096 // \ingroup columns
4097 //
4098 // \param lhs The target left-hand side column selection.
4099 // \param rhs The right-hand side matrix of bits to shift.
4100 // \param row The row index of the first element to be modified.
4101 // \param column The column index of the first element to be modified.
4102 // \return \a true in case the assignment would be successful, \a false if not.
4103 //
4104 // This function must \b NOT be called explicitly! It is used internally for the performance
4105 // optimized evaluation of expression templates. Calling this function explicitly might result
4106 // in erroneous results and/or in compilation errors. Instead of using this function use the
4107 // assignment operator.
4108 */
4109 template< typename MT1      // Type of the matrix
4110         , bool SO1          // Storage order
4111         , bool DF           // Density flag
4112         , bool SF           // Symmetry flag
4113         , typename... CCAs  // Compile time column arguments
4114         , typename MT2      // Type of the right-hand side matrix
4115         , bool SO2 >        // Storage order of the right-hand side matrix
tryShiftAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)4116 inline bool tryShiftAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
4117                             const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4118 {
4119    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4120    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4121    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4122    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4123 
4124    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
4125       if( !tryShiftAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
4126          return false;
4127    }
4128 
4129    return true;
4130 }
4131 /*! \endcond */
4132 //*************************************************************************************************
4133 
4134 
4135 //*************************************************************************************************
4136 /*! \cond BLAZE_INTERNAL */
4137 /*!\brief Predict invariant violations by the bitwise AND assignment of a column vector to a
4138 //        column selection.
4139 // \ingroup columns
4140 //
4141 // \param lhs The target left-hand side column selection.
4142 // \param rhs The right-hand side column vector for the bitwise AND operation.
4143 // \param row The row index of the first element to be modified.
4144 // \param column The column index of the first element to be modified.
4145 // \return \a true in case the assignment would be successful, \a false if not.
4146 //
4147 // This function must \b NOT be called explicitly! It is used internally for the performance
4148 // optimized evaluation of expression templates. Calling this function explicitly might result
4149 // in erroneous results and/or in compilation errors. Instead of using this function use the
4150 // assignment operator.
4151 */
4152 template< typename MT       // Type of the matrix
4153         , bool SO           // Storage order
4154         , bool DF           // Density flag
4155         , bool SF           // Symmetry flag
4156         , typename... CCAs  // Compile time column arguments
4157         , typename VT >     // Type of the right-hand side vector
tryBitandAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)4158 inline bool tryBitandAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4159                              const Vector<VT,false>& rhs, size_t row, size_t column )
4160 {
4161    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4162    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4163    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4164 
4165    return tryBitandAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
4166 }
4167 /*! \endcond */
4168 //*************************************************************************************************
4169 
4170 
4171 //*************************************************************************************************
4172 /*! \cond BLAZE_INTERNAL */
4173 /*!\brief Predict invariant violations by the bitwise AND assignment of a row vector to a column
4174 //        selection.
4175 // \ingroup columns
4176 //
4177 // \param lhs The target left-hand side column selection.
4178 // \param rhs The right-hand side row vector for the bitwise AND operation.
4179 // \param row The row index of the first element to be modified.
4180 // \param column The column index of the first element to be modified.
4181 // \return \a true in case the assignment would be successful, \a false if not.
4182 //
4183 // This function must \b NOT be called explicitly! It is used internally for the performance
4184 // optimized evaluation of expression templates. Calling this function explicitly might result
4185 // in erroneous results and/or in compilation errors. Instead of using this function use the
4186 // assignment operator.
4187 */
4188 template< typename MT       // Type of the matrix
4189         , bool SO           // Storage order
4190         , bool DF           // Density flag
4191         , bool SF           // Symmetry flag
4192         , typename... CCAs  // Compile time column arguments
4193         , typename VT >     // Type of the right-hand side vector
tryBitandAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)4194 inline bool tryBitandAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4195                              const Vector<VT,true>& rhs, size_t row, size_t column )
4196 {
4197    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4198    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4199    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4200 
4201    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4202       if( !tryBitand( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
4203          return false;
4204    }
4205 
4206    return true;
4207 }
4208 /*! \endcond */
4209 //*************************************************************************************************
4210 
4211 
4212 //*************************************************************************************************
4213 /*! \cond BLAZE_INTERNAL */
4214 /*!\brief Predict invariant violations by the bitwise AND assignment of a vector to the band of
4215 //        a column selection.
4216 // \ingroup columns
4217 //
4218 // \param lhs The target left-hand side column selection.
4219 // \param rhs The right-hand side vector for the bitwise AND operation.
4220 // \param band The index of the band the right-hand side vector is assigned to.
4221 // \param row The row index of the first element to be modified.
4222 // \param column The column index of the first element to be modified.
4223 // \return \a true in case the assignment would be successful, \a false if not.
4224 //
4225 // This function must \b NOT be called explicitly! It is used internally for the performance
4226 // optimized evaluation of expression templates. Calling this function explicitly might result
4227 // in erroneous results and/or in compilation errors. Instead of using this function use the
4228 // assignment operator.
4229 */
4230 template< typename MT       // Type of the matrix
4231         , bool SO           // Storage order
4232         , bool DF           // Density flag
4233         , bool SF           // Symmetry flag
4234         , typename... CCAs  // Compile time column arguments
4235         , typename VT       // Type of the right-hand side vector
4236         , bool TF >         // Transpose flag of the right-hand side vector
tryBitandAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)4237 inline bool tryBitandAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4238                              const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4239 {
4240    MAYBE_UNUSED( band );
4241 
4242    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4243    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4244    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4245    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4246 
4247    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4248       if( !tryBitand( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
4249          return false;
4250    }
4251 
4252    return true;
4253 }
4254 /*! \endcond */
4255 //*************************************************************************************************
4256 
4257 
4258 //*************************************************************************************************
4259 /*! \cond BLAZE_INTERNAL */
4260 /*!\brief Predict invariant violations by the bitwise AND assignment of a matrix to a column
4261 //        selection.
4262 // \ingroup columns
4263 //
4264 // \param lhs The target left-hand side column selection.
4265 // \param rhs The right-hand side matrix for the bitwise AND operation.
4266 // \param row The row index of the first element to be modified.
4267 // \param column The column index of the first element to be modified.
4268 // \return \a true in case the assignment would be successful, \a false if not.
4269 //
4270 // This function must \b NOT be called explicitly! It is used internally for the performance
4271 // optimized evaluation of expression templates. Calling this function explicitly might result
4272 // in erroneous results and/or in compilation errors. Instead of using this function use the
4273 // assignment operator.
4274 */
4275 template< typename MT1      // Type of the matrix
4276         , bool SO1          // Storage order
4277         , bool DF           // Density flag
4278         , bool SF           // Symmetry flag
4279         , typename... CCAs  // Compile time column arguments
4280         , typename MT2      // Type of the right-hand side matrix
4281         , bool SO2 >        // Storage order of the right-hand side matrix
tryBitandAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)4282 inline bool tryBitandAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
4283                              const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4284 {
4285    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4286    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4287    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4288    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4289 
4290    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
4291       if( !tryBitandAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
4292          return false;
4293    }
4294 
4295    return true;
4296 }
4297 /*! \endcond */
4298 //*************************************************************************************************
4299 
4300 
4301 //*************************************************************************************************
4302 /*! \cond BLAZE_INTERNAL */
4303 /*!\brief Predict invariant violations by the bitwise OR assignment of a column vector to a
4304 //        column selection.
4305 // \ingroup columns
4306 //
4307 // \param lhs The target left-hand side column selection.
4308 // \param rhs The right-hand side column vector for the bitwise OR operation.
4309 // \param row The row index of the first element to be modified.
4310 // \param column The column index of the first element to be modified.
4311 // \return \a true in case the assignment would be successful, \a false if not.
4312 //
4313 // This function must \b NOT be called explicitly! It is used internally for the performance
4314 // optimized evaluation of expression templates. Calling this function explicitly might result
4315 // in erroneous results and/or in compilation errors. Instead of using this function use the
4316 // assignment operator.
4317 */
4318 template< typename MT       // Type of the matrix
4319         , bool SO           // Storage order
4320         , bool DF           // Density flag
4321         , bool SF           // Symmetry flag
4322         , typename... CCAs  // Compile time column arguments
4323         , typename VT >     // Type of the right-hand side vector
tryBitorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)4324 inline bool tryBitorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4325                             const Vector<VT,false>& rhs, size_t row, size_t column )
4326 {
4327    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4328    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4329    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4330 
4331    return tryBitorAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
4332 }
4333 /*! \endcond */
4334 //*************************************************************************************************
4335 
4336 
4337 //*************************************************************************************************
4338 /*! \cond BLAZE_INTERNAL */
4339 /*!\brief Predict invariant violations by the bitwise OR assignment of a row vector to a column
4340 //        selection.
4341 // \ingroup columns
4342 //
4343 // \param lhs The target left-hand side column selection.
4344 // \param rhs The right-hand side row vector for the bitwise OR operation.
4345 // \param row The row index of the first element to be modified.
4346 // \param column The column index of the first element to be modified.
4347 // \return \a true in case the assignment would be successful, \a false if not.
4348 //
4349 // This function must \b NOT be called explicitly! It is used internally for the performance
4350 // optimized evaluation of expression templates. Calling this function explicitly might result
4351 // in erroneous results and/or in compilation errors. Instead of using this function use the
4352 // assignment operator.
4353 */
4354 template< typename MT       // Type of the matrix
4355         , bool SO           // Storage order
4356         , bool DF           // Density flag
4357         , bool SF           // Symmetry flag
4358         , typename... CCAs  // Compile time column arguments
4359         , typename VT >     // Type of the right-hand side vector
tryBitorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)4360 inline bool tryBitorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4361                             const Vector<VT,true>& rhs, size_t row, size_t column )
4362 {
4363    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4364    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4365    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4366 
4367    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4368       if( !tryBitor( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
4369          return false;
4370    }
4371 
4372    return true;
4373 }
4374 /*! \endcond */
4375 //*************************************************************************************************
4376 
4377 
4378 //*************************************************************************************************
4379 /*! \cond BLAZE_INTERNAL */
4380 /*!\brief Predict invariant violations by the bitwise OR assignment of a vector to the band of
4381 //        a column selection.
4382 // \ingroup columns
4383 //
4384 // \param lhs The target left-hand side column selection.
4385 // \param rhs The right-hand side vector for the bitwise OR operation.
4386 // \param band The index of the band the right-hand side vector is assigned to.
4387 // \param row The row index of the first element to be modified.
4388 // \param column The column index of the first element to be modified.
4389 // \return \a true in case the assignment would be successful, \a false if not.
4390 //
4391 // This function must \b NOT be called explicitly! It is used internally for the performance
4392 // optimized evaluation of expression templates. Calling this function explicitly might result
4393 // in erroneous results and/or in compilation errors. Instead of using this function use the
4394 // assignment operator.
4395 */
4396 template< typename MT       // Type of the matrix
4397         , bool SO           // Storage order
4398         , bool DF           // Density flag
4399         , bool SF           // Symmetry flag
4400         , typename... CCAs  // Compile time column arguments
4401         , typename VT       // Type of the right-hand side vector
4402         , bool TF >         // Transpose flag of the right-hand side vector
tryBitorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)4403 inline bool tryBitorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4404                             const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4405 {
4406    MAYBE_UNUSED( band );
4407 
4408    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4409    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4410    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4411    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4412 
4413    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4414       if( !tryBitor( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
4415          return false;
4416    }
4417 
4418    return true;
4419 }
4420 /*! \endcond */
4421 //*************************************************************************************************
4422 
4423 
4424 //*************************************************************************************************
4425 /*! \cond BLAZE_INTERNAL */
4426 /*!\brief Predict invariant violations by the bitwise OR assignment of a matrix to a column
4427 //        selection.
4428 // \ingroup columns
4429 //
4430 // \param lhs The target left-hand side column selection.
4431 // \param rhs The right-hand side matrix for the bitwise OR operation.
4432 // \param row The row index of the first element to be modified.
4433 // \param column The column index of the first element to be modified.
4434 // \return \a true in case the assignment would be successful, \a false if not.
4435 //
4436 // This function must \b NOT be called explicitly! It is used internally for the performance
4437 // optimized evaluation of expression templates. Calling this function explicitly might result
4438 // in erroneous results and/or in compilation errors. Instead of using this function use the
4439 // assignment operator.
4440 */
4441 template< typename MT1      // Type of the matrix
4442         , bool SO1          // Storage order
4443         , bool DF           // Density flag
4444         , bool SF           // Symmetry flag
4445         , typename... CCAs  // Compile time column arguments
4446         , typename MT2      // Type of the right-hand side matrix
4447         , bool SO2 >        // Storage order of the right-hand side matrix
tryBitorAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)4448 inline bool tryBitorAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
4449                             const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4450 {
4451    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4452    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4453    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4454    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4455 
4456    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
4457       if( !tryBitorAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
4458          return false;
4459    }
4460 
4461    return true;
4462 }
4463 /*! \endcond */
4464 //*************************************************************************************************
4465 
4466 
4467 //*************************************************************************************************
4468 /*! \cond BLAZE_INTERNAL */
4469 /*!\brief Predict invariant violations by the bitwise XOR assignment of a column vector to a
4470 //        column selection.
4471 // \ingroup columns
4472 //
4473 // \param lhs The target left-hand side column selection.
4474 // \param rhs The right-hand side column vector for the bitwise XOR operation.
4475 // \param row The row index of the first element to be modified.
4476 // \param column The column index of the first element to be modified.
4477 // \return \a true in case the assignment would be successful, \a false if not.
4478 //
4479 // This function must \b NOT be called explicitly! It is used internally for the performance
4480 // optimized evaluation of expression templates. Calling this function explicitly might result
4481 // in erroneous results and/or in compilation errors. Instead of using this function use the
4482 // assignment operator.
4483 */
4484 template< typename MT       // Type of the matrix
4485         , bool SO           // Storage order
4486         , bool DF           // Density flag
4487         , bool SF           // Symmetry flag
4488         , typename... CCAs  // Compile time column arguments
4489         , typename VT >     // Type of the right-hand side vector
tryBitxorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,false> & rhs,size_t row,size_t column)4490 inline bool tryBitxorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4491                              const Vector<VT,false>& rhs, size_t row, size_t column )
4492 {
4493    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4494    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4495    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4496 
4497    return tryBitxorAssign( lhs.operand(), *rhs, row, lhs.idx( column ) );
4498 }
4499 /*! \endcond */
4500 //*************************************************************************************************
4501 
4502 
4503 //*************************************************************************************************
4504 /*! \cond BLAZE_INTERNAL */
4505 /*!\brief Predict invariant violations by the bitwise XOR assignment of a row vector to a column
4506 //        selection.
4507 // \ingroup columns
4508 //
4509 // \param lhs The target left-hand side column selection.
4510 // \param rhs The right-hand side row vector for the bitwise XOR operation.
4511 // \param row The row index of the first element to be modified.
4512 // \param column The column index of the first element to be modified.
4513 // \return \a true in case the assignment would be successful, \a false if not.
4514 //
4515 // This function must \b NOT be called explicitly! It is used internally for the performance
4516 // optimized evaluation of expression templates. Calling this function explicitly might result
4517 // in erroneous results and/or in compilation errors. Instead of using this function use the
4518 // assignment operator.
4519 */
4520 template< typename MT       // Type of the matrix
4521         , bool SO           // Storage order
4522         , bool DF           // Density flag
4523         , bool SF           // Symmetry flag
4524         , typename... CCAs  // Compile time column arguments
4525         , typename VT >     // Type of the right-hand side vector
tryBitxorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,true> & rhs,size_t row,size_t column)4526 inline bool tryBitxorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4527                              const Vector<VT,true>& rhs, size_t row, size_t column )
4528 {
4529    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4530    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4531    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4532 
4533    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4534       if( !tryBitxor( lhs.operand(), row, lhs.idx( column+i ), (*rhs)[i] ) )
4535          return false;
4536    }
4537 
4538    return true;
4539 }
4540 /*! \endcond */
4541 //*************************************************************************************************
4542 
4543 
4544 //*************************************************************************************************
4545 /*! \cond BLAZE_INTERNAL */
4546 /*!\brief Predict invariant violations by the bitwise XOR assignment of a vector to the band of
4547 //        a column selection.
4548 // \ingroup columns
4549 //
4550 // \param lhs The target left-hand side column selection.
4551 // \param rhs The right-hand side vector for the bitwise XOR operation.
4552 // \param band The index of the band the right-hand side vector is assigned to.
4553 // \param row The row index of the first element to be modified.
4554 // \param column The column index of the first element to be modified.
4555 // \return \a true in case the assignment would be successful, \a false if not.
4556 //
4557 // This function must \b NOT be called explicitly! It is used internally for the performance
4558 // optimized evaluation of expression templates. Calling this function explicitly might result
4559 // in erroneous results and/or in compilation errors. Instead of using this function use the
4560 // assignment operator.
4561 */
4562 template< typename MT       // Type of the matrix
4563         , bool SO           // Storage order
4564         , bool DF           // Density flag
4565         , bool SF           // Symmetry flag
4566         , typename... CCAs  // Compile time column arguments
4567         , typename VT       // Type of the right-hand side vector
4568         , bool TF >         // Transpose flag of the right-hand side vector
tryBitxorAssign(const Columns<MT,SO,DF,SF,CCAs...> & lhs,const Vector<VT,TF> & rhs,ptrdiff_t band,size_t row,size_t column)4569 inline bool tryBitxorAssign( const Columns<MT,SO,DF,SF,CCAs...>& lhs,
4570                              const Vector<VT,TF>& rhs, ptrdiff_t band, size_t row, size_t column )
4571 {
4572    MAYBE_UNUSED( band );
4573 
4574    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4575    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4576    BLAZE_INTERNAL_ASSERT( row + (*rhs).size() <= lhs.rows(), "Invalid number of rows" );
4577    BLAZE_INTERNAL_ASSERT( column + (*rhs).size() <= lhs.columns(), "Invalid number of columns" );
4578 
4579    for( size_t i=0UL; i<(*rhs).size(); ++i ) {
4580       if( !tryBitxor( lhs.operand(), row+i, lhs.idx( column+i ), (*rhs)[i] ) )
4581          return false;
4582    }
4583 
4584    return true;
4585 }
4586 /*! \endcond */
4587 //*************************************************************************************************
4588 
4589 
4590 //*************************************************************************************************
4591 /*! \cond BLAZE_INTERNAL */
4592 /*!\brief Predict invariant violations by the bitwise XOR assignment of a matrix to a column
4593 //        selection.
4594 // \ingroup columns
4595 //
4596 // \param lhs The target left-hand side column selection.
4597 // \param rhs The right-hand side matrix for the bitwise XOR operation.
4598 // \param row The row index of the first element to be modified.
4599 // \param column The column index of the first element to be modified.
4600 // \return \a true in case the assignment would be successful, \a false if not.
4601 //
4602 // This function must \b NOT be called explicitly! It is used internally for the performance
4603 // optimized evaluation of expression templates. Calling this function explicitly might result
4604 // in erroneous results and/or in compilation errors. Instead of using this function use the
4605 // assignment operator.
4606 */
4607 template< typename MT1      // Type of the matrix
4608         , bool SO1          // Storage order
4609         , bool DF           // Density flag
4610         , bool SF           // Symmetry flag
4611         , typename... CCAs  // Compile time column arguments
4612         , typename MT2      // Type of the right-hand side matrix
4613         , bool SO2 >        // Storage order of the right-hand side matrix
tryBitxorAssign(const Columns<MT1,SO1,DF,SF,CCAs...> & lhs,const Matrix<MT2,SO2> & rhs,size_t row,size_t column)4614 inline bool tryBitxorAssign( const Columns<MT1,SO1,DF,SF,CCAs...>& lhs,
4615                              const Matrix<MT2,SO2>& rhs, size_t row, size_t column )
4616 {
4617    BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
4618    BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
4619    BLAZE_INTERNAL_ASSERT( row + (*rhs).rows() <= lhs.rows(), "Invalid number of rows" );
4620    BLAZE_INTERNAL_ASSERT( column + (*rhs).columns() <= lhs.columns(), "Invalid number of columns" );
4621 
4622    for( size_t j=0UL; j<(*rhs).columns(); ++j ) {
4623       if( !tryBitxorAssign( lhs.operand(), blaze::column( *rhs, j, unchecked ), row, lhs.idx( column+j ) ) )
4624          return false;
4625    }
4626 
4627    return true;
4628 }
4629 /*! \endcond */
4630 //*************************************************************************************************
4631 
4632 
4633 //*************************************************************************************************
4634 /*! \cond BLAZE_INTERNAL */
4635 /*!\brief Removal of all restrictions on the data access to the given column selection.
4636 // \ingroup columns
4637 //
4638 // \param c The column selection to be derestricted.
4639 // \return Column selection without access restrictions.
4640 //
4641 // This function removes all restrictions on the data access to the given column selection.
4642 // It returns a column selection that does provide the same interface but does not have any
4643 // restrictions on the data access.\n
4644 // This function must \b NOT be called explicitly! It is used internally for the performance
4645 // optimized evaluation of expression templates. Calling this function explicitly might result
4646 // in the violation of invariants, erroneous results and/or in compilation errors.
4647 */
4648 template< typename MT         // Type of the matrix
4649         , bool SO             // Storage order
4650         , bool DF             // Density flag
4651         , bool SF             // Symmetry flag
4652         , typename... CCAs >  // Compile time column arguments
decltype(auto)4653 inline decltype(auto) derestrict( Columns<MT,SO,DF,SF,CCAs...>& c )
4654 {
4655    return columns( derestrict( c.operand() ), c.idces(), unchecked );
4656 }
4657 /*! \endcond */
4658 //*************************************************************************************************
4659 
4660 
4661 //*************************************************************************************************
4662 /*! \cond BLAZE_INTERNAL */
4663 /*!\brief Removal of all restrictions on the data access to the given temporary column selection.
4664 // \ingroup columns
4665 //
4666 // \param r The temporary column selection to be derestricted.
4667 // \return Column selection without access restrictions.
4668 //
4669 // This function removes all restrictions on the data access to the given temporary column selection.
4670 // It returns a column selection that does provide the same interface but does not have any
4671 // restrictions on the data access.\n
4672 // This function must \b NOT be called explicitly! It is used internally for the performance
4673 // optimized evaluation of expression templates. Calling this function explicitly might result
4674 // in the violation of invariants, erroneous results and/or in compilation errors.
4675 */
4676 template< typename MT         // Type of the matrix
4677         , bool SO             // Storage order
4678         , bool DF             // Density flag
4679         , bool SF             // Symmetry flag
4680         , typename... CCAs >  // Compile time column arguments
decltype(auto)4681 inline decltype(auto) derestrict( Columns<MT,SO,DF,SF,CCAs...>&& c )
4682 {
4683    return columns( derestrict( c.operand() ), c.idces(), unchecked );
4684 }
4685 /*! \endcond */
4686 //*************************************************************************************************
4687 
4688 
4689 //*************************************************************************************************
4690 /*! \cond BLAZE_INTERNAL */
4691 /*!\brief Returns a reference to the underlying matrix of the given column selection.
4692 // \ingroup columns
4693 //
4694 // \param c The given column selection.
4695 // \return Reference to the underlying matrix.
4696 //
4697 // This function returns a reference to the underlying matrix of the given column selection.\n
4698 // This function must \b NOT be called explicitly! It is used internally for the performance
4699 // optimized evaluation of expression templates. Calling this function explicitly might result
4700 // in the violation of invariants, erroneous results and/or in compilation errors.
4701 */
4702 template< typename MT         // Type of the matrix
4703         , bool SO             // Storage order
4704         , bool DF             // Density flag
4705         , bool SF             // Symmetry flag
4706         , typename... CCAs >  // Compile time column arguments
decltype(auto)4707 inline decltype(auto) unview( Columns<MT,SO,DF,SF,CCAs...>& c )
4708 {
4709    return c.operand();
4710 }
4711 /*! \endcond */
4712 //*************************************************************************************************
4713 
4714 
4715 //*************************************************************************************************
4716 /*! \cond BLAZE_INTERNAL */
4717 /*!\brief Returns a reference to the underlying matrix of the given constant column selection.
4718 // \ingroup columns
4719 //
4720 // \param c The given constant column selection.
4721 // \return Reference to the underlying matrix.
4722 //
4723 // This function returns a reference to the underlying matrix of the given constant column
4724 // selection.\n
4725 // This function must \b NOT be called explicitly! It is used internally for the performance
4726 // optimized evaluation of expression templates. Calling this function explicitly might result
4727 // in the violation of invariants, erroneous results and/or in compilation errors.
4728 */
4729 template< typename MT         // Type of the matrix
4730         , bool SO             // Storage order
4731         , bool DF             // Density flag
4732         , bool SF             // Symmetry flag
4733         , typename... CCAs >  // Compile time column arguments
decltype(auto)4734 inline decltype(auto) unview( const Columns<MT,SO,DF,SF,CCAs...>& c )
4735 {
4736    return c.operand();
4737 }
4738 /*! \endcond */
4739 //*************************************************************************************************
4740 
4741 
4742 
4743 
4744 //=================================================================================================
4745 //
4746 //  SIZE SPECIALIZATIONS
4747 //
4748 //=================================================================================================
4749 
4750 //*************************************************************************************************
4751 /*! \cond BLAZE_INTERNAL */
4752 template< typename MT, bool SO, bool DF, bool SF, typename... CCAs >
4753 struct Size< Columns<MT,SO,DF,SF,CCAs...>, 0UL >
4754    : public Size<MT,0UL>
4755 {};
4756 
4757 template< typename MT, bool SO, bool DF, bool SF, size_t I, size_t... Is, typename... CCAs >
4758 struct Size< Columns<MT,SO,DF,SF,index_sequence<I,Is...>,CCAs...>, 1UL >
4759    : public Ptrdiff_t<1UL+sizeof...(Is)>
4760 {};
4761 /*! \endcond */
4762 //*************************************************************************************************
4763 
4764 
4765 
4766 
4767 //=================================================================================================
4768 //
4769 //  MAXSIZE SPECIALIZATIONS
4770 //
4771 //=================================================================================================
4772 
4773 //*************************************************************************************************
4774 /*! \cond BLAZE_INTERNAL */
4775 template< typename MT, bool SO, bool DF, bool SF, typename... CCAs >
4776 struct MaxSize< Columns<MT,SO,DF,SF,CCAs...>, 0UL >
4777    : public MaxSize<MT,0UL>
4778 {};
4779 
4780 template< typename MT, bool SO, bool DF, bool SF, size_t I, size_t... Is, typename... CCAs >
4781 struct MaxSize< Columns<MT,SO,DF,SF,index_sequence<I,Is...>,CCAs...>, 1UL >
4782    : public Ptrdiff_t<1UL+sizeof...(Is)>
4783 {};
4784 /*! \endcond */
4785 //*************************************************************************************************
4786 
4787 
4788 
4789 
4790 //=================================================================================================
4791 //
4792 //  ISRESTRICTED SPECIALIZATIONS
4793 //
4794 //=================================================================================================
4795 
4796 //*************************************************************************************************
4797 /*! \cond BLAZE_INTERNAL */
4798 template< typename MT, bool SO, bool DF, bool SF, typename... CCAs >
4799 struct IsRestricted< Columns<MT,SO,DF,SF,CCAs...> >
4800    : public IsRestricted<MT>
4801 {};
4802 /*! \endcond */
4803 //*************************************************************************************************
4804 
4805 
4806 
4807 
4808 //=================================================================================================
4809 //
4810 //  HASCONSTDATAACCESS SPECIALIZATIONS
4811 //
4812 //=================================================================================================
4813 
4814 //*************************************************************************************************
4815 /*! \cond BLAZE_INTERNAL */
4816 template< typename MT, bool SO, bool SF, typename... CCAs >
4817 struct HasConstDataAccess< Columns<MT,SO,true,SF,CCAs...> >
4818    : public HasConstDataAccess<MT>
4819 {};
4820 /*! \endcond */
4821 //*************************************************************************************************
4822 
4823 
4824 
4825 
4826 //=================================================================================================
4827 //
4828 //  HASMUTABLEDATAACCESS SPECIALIZATIONS
4829 //
4830 //=================================================================================================
4831 
4832 //*************************************************************************************************
4833 /*! \cond BLAZE_INTERNAL */
4834 template< typename MT, bool SO, bool SF, typename... CCAs >
4835 struct HasMutableDataAccess< Columns<MT,SO,true,SF,CCAs...> >
4836    : public HasMutableDataAccess<MT>
4837 {};
4838 /*! \endcond */
4839 //*************************************************************************************************
4840 
4841 
4842 
4843 
4844 //=================================================================================================
4845 //
4846 //  ISALIGNED SPECIALIZATIONS
4847 //
4848 //=================================================================================================
4849 
4850 //*************************************************************************************************
4851 /*! \cond BLAZE_INTERNAL */
4852 template< typename MT, bool SO, bool SF, typename... CCAs >
4853 struct IsAligned< Columns<MT,SO,true,SF,CCAs...> >
4854    : public IsAligned<MT>
4855 {};
4856 /*! \endcond */
4857 //*************************************************************************************************
4858 
4859 } // namespace blaze
4860 
4861 #endif
4862