GCC Code Coverage Report


Directory: ./
File: Core/array_1d.hpp
Date: 2024-04-14 07:32:34
Exec Total Coverage
Lines: 50 53 94.3%
Branches: 9 22 40.9%

Line Branch Exec Source
1 // ______ ______ _ _ _____ ______
2 // | ____| ____| | (_)/ ____| | ____|
3 // | |__ | |__ | | _| (___ ___| |__
4 // | __| | __| | | | |\___ \ / __| __|
5 // | | | |____| |____| |____) | (__| |____
6 // |_| |______|______|_|_____/ \___|______|
7 // Finite Elements for Life Sciences and Engineering
8 //
9 // License: LGL2.1 License
10 // FELiScE default license: LICENSE in root folder
11 //
12 // Main authors: Vicente Mataix Ferrandiz
13 //
14
15 #if !defined(FELISCE_ARRAY_1D_H_INCLUDED )
16 #define FELISCE_ARRAY_1D_H_INCLUDED
17
18 // System includes
19 #include <string>
20 #include <iostream>
21 #include <array>
22
23 // External includes
24 #include <boost/numeric/ublas/vector_expression.hpp>
25 #include <boost/numeric/ublas/storage.hpp>
26 #include <boost/numeric/ublas/detail/vector_assign.hpp>
27
28 // Project includes
29 #include "Core/shared_pointers.hpp"
30
31 namespace felisce
32 {
33
34 ///@name felisce Globals
35 ///@{
36
37 ///@}
38 ///@name Type Definitions
39 ///@{
40
41 ///@}
42 ///@name Enum's
43 ///@{
44
45 ///@}
46 ///@name Functions
47 ///@{
48
49 ///@}
50 ///@name felisce Classes
51 ///@{
52
53 /**
54 * @class array_1d
55 * @ingroup Core
56 * @brief This class defines an efficient array compatible with Ublas, so it is possible to apply operations like norm, sum, etc..
57 * @details Can be used to define the doubles arrays. Inspired in https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/containers/array_1d.h
58 * @author Vicente Mataix Ferrandiz
59 */
60 template<class T, std::size_t N>
61 class array_1d
62 : public boost::numeric::ublas::vector_expression<array_1d<T, N>>
63 {
64 public:
65 ///@name Type Definitions
66 ///@{
67
68 /// Pointer definition of array_1d
69 FELISCE_CLASS_POINTER_DEFINITION(array_1d);
70
71 typedef std::size_t size_type;
72 typedef std::ptrdiff_t difference_type;
73 typedef T value_type;
74 typedef typename boost::numeric::ublas::type_traits<T>::const_reference const_reference;
75 typedef T &reference;
76 typedef std::array<T,N> array_type;
77 typedef T *pointer;
78 typedef array_1d<T, N> self_type;
79 typedef const boost::numeric::ublas::vector_reference<const self_type> const_closure_type;
80 typedef boost::numeric::ublas::vector_reference<self_type> closure_type;
81 typedef self_type vector_temporary_type;
82 typedef boost::numeric::ublas::dense_tag storage_category;
83
84 ///@}
85 ///@name Life Cycle
86 ///@{
87
88 /// Default constructor.
89 BOOST_UBLAS_INLINE
90 1160607 array_1d ():
91 1160607 boost::numeric::ublas::vector_expression<self_type> ()
92 {
93 1160607 }
94
95 explicit BOOST_UBLAS_INLINE
96 8 array_1d (value_type v):
97 8 boost::numeric::ublas::vector_expression<self_type> ()
98 {
99
1/2
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
8 std::fill (data().begin(), data().begin() + N, v);
100 8 }
101
102 BOOST_UBLAS_INLINE
103 array_1d (const array_type & rdata):
104 boost::numeric::ublas::vector_expression<self_type> (),
105 data_ (rdata) {}
106
107 BOOST_UBLAS_INLINE
108 365340 array_1d (const array_1d &v):
109 boost::numeric::ublas::vector_expression<self_type> (),
110 365340 data_ (v.data_) {}
111
112 template<class AE>
113 BOOST_UBLAS_INLINE
114 2633624 array_1d (const boost::numeric::ublas::vector_expression<AE> &ae)
115 2633624 {
116
1/2
✓ Branch 1 taken 1316812 times.
✗ Branch 2 not taken.
2633624 boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_assign> (*this, ae);
117 2633624 }
118
119 ///@}
120 ///@name Operators
121 ///@{
122
123 // Element access
124 BOOST_UBLAS_INLINE
125 46086354 const_reference operator () (size_type i) const
126 {
127 46086354 return data_[i];
128 }
129
130 BOOST_UBLAS_INLINE
131 16993557 reference operator () (size_type i)
132 {
133 16993557 return data_[i];
134 }
135
136 BOOST_UBLAS_INLINE
137 3464838 const_reference operator [] (size_type i) const
138 {
139 3464838 return data_[i];
140 }
141
142 BOOST_UBLAS_INLINE
143 13104774 reference operator [] (size_type i)
144 {
145 13104774 return data_[i];
146 }
147
148 // Assignment
149 BOOST_UBLAS_INLINE
150 189319 array_1d &operator = (const array_1d &v)
151 {
152 189319 data_ = v.data_;
153 189319 return *this;
154 }
155
156 template<class AE>
157 BOOST_UBLAS_INLINE
158 518512 array_1d &operator = (const boost::numeric::ublas::vector_expression<AE> &ae)
159 {
160
1/2
✓ Branch 2 taken 259256 times.
✗ Branch 3 not taken.
518512 return assign (self_type (ae));
161 }
162
163 template<class AE>
164 BOOST_UBLAS_INLINE
165 827211 array_1d &operator += (const boost::numeric::ublas::vector_expression<AE> &ae)
166 {
167
2/4
✓ Branch 2 taken 413606 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 413606 times.
✗ Branch 6 not taken.
827211 return assign (self_type (*this + ae));
168 }
169
170 template<class AE>
171 BOOST_UBLAS_INLINE
172 69940 array_1d &operator -= (const boost::numeric::ublas::vector_expression<AE> &ae)
173 {
174
2/4
✓ Branch 2 taken 34971 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 34971 times.
✗ Branch 6 not taken.
69940 return assign (self_type (*this - ae));
175 }
176
177 template<class AT>
178 BOOST_UBLAS_INLINE
179 143261 array_1d &operator /= (const AT &at)
180 {
181 143261 boost::numeric::ublas::vector_assign_scalar<boost::numeric::ublas::scalar_divides_assign> (*this, at);
182 143261 return *this;
183 }
184
185 ///@}
186 ///@name Operations
187 ///@{
188
189 // Resizing
190 BOOST_UBLAS_INLINE
191 void resize (size_type array_size, bool preserve = true)
192 {
193 static_cast<void>(array_size);
194 if (!preserve)
195 std::fill (data_.begin(), data_.end(), value_type ());
196 }
197
198 BOOST_UBLAS_INLINE
199 array_1d &assign_temporary (array_1d &v)
200 {
201 swap (v);
202 return *this;
203 }
204
205 template<class AT>
206 BOOST_UBLAS_INLINE
207 104908 array_1d &operator *= (const AT &at)
208 {
209 104908 boost::numeric::ublas::vector_assign_scalar<boost::numeric::ublas::scalar_multiplies_assign> (*this, at);
210 104908 return *this;
211 }
212 template<class AE>
213 BOOST_UBLAS_INLINE
214 array_1d &plus_assign (const boost::numeric::ublas::vector_expression<AE> &ae)
215 {
216 boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_plus_assign> (*this, ae);
217 return *this;
218 }
219 template<class AE>
220 BOOST_UBLAS_INLINE
221 1625477 array_1d &assign (const boost::numeric::ublas::vector_expression<AE> &ae)
222 {
223 1625477 boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_assign> (*this, ae);
224 1625477 return *this;
225 }
226 // Swapping
227 BOOST_UBLAS_INLINE
228 1 void swap (array_1d &v)
229 {
230
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (this != &v) {
231 1 data ().swap (v.data ());
232 }
233 1 }
234
235 #ifndef BOOST_UBLAS_NO_MEMBER_FRIENDS
236 BOOST_UBLAS_INLINE
237 friend void swap (array_1d &v1, array_1d &v2)
238 {
239 v1.swap (v2);
240 }
241 #endif
242
243 // Element assignment
244 BOOST_UBLAS_INLINE
245 reference insert_element (size_type i, const_reference t)
246 {
247 BOOST_UBLAS_CHECK (i < N, boost::numeric::ublas::bad_index ());
248 return (data_ [i] = t);
249 }
250
251 BOOST_UBLAS_INLINE
252 void erase_element (size_type i)
253 {
254 BOOST_UBLAS_CHECK (i < N, boost::numeric::ublas::bad_index ());
255 data_ [i] = value_type/*zero*/();
256 }
257
258 BOOST_UBLAS_INLINE
259 92066 void clear ()
260 {
261 // Previously: data ().clear ();
262
1/2
✓ Branch 5 taken 46037 times.
✗ Branch 6 not taken.
92066 std::fill (data ().begin (), data ().end (), value_type (0));
263 92066 }
264
265 ///@}
266 ///@name Access
267 ///@{
268
269 // Iterator types
270 private:
271 // Use the storage array1 iterator
272 typedef typename array_type::const_iterator const_iterator_type;
273 typedef typename array_type::iterator iterator_type;
274
275 public:
276 #ifdef BOOST_UBLAS_USE_INDEXED_ITERATOR
277 typedef indexed_iterator<self_type, dense_random_access_iterator_tag> iterator;
278 typedef indexed_const_iterator<self_type, dense_random_access_iterator_tag> const_iterator;
279 #else
280 class const_iterator;
281 class iterator;
282 #endif
283
284 // Element lookup
285 BOOST_UBLAS_INLINE
286 const_iterator find (size_type i) const
287 {
288 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
289 return const_iterator (*this, data ().begin () + i);
290 #else
291 return const_iterator (*this, i);
292 #endif
293 }
294 BOOST_UBLAS_INLINE
295 iterator find (size_type i)
296 {
297 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
298 return iterator (*this, data ().begin () + i);
299 #else
300 return iterator (*this, i);
301 #endif
302 }
303
304 BOOST_UBLAS_INLINE
305 14336348 size_type size () const
306 {
307 14336348 return N;
308 }
309
310 template<class AE>
311 BOOST_UBLAS_INLINE
312 array_1d &minus_assign (const boost::numeric::ublas::vector_expression<AE> &ae)
313 {
314 boost::numeric::ublas::vector_assign<boost::numeric::ublas::scalar_minus_assign>(*this,ae);
315 //vector_assign (scalar_minus_assign<reference, typename AE::value_type> (), *this, ae);
316 return *this;
317 }
318
319 BOOST_UBLAS_INLINE
320 const array_type &data () const
321 {
322 return data_;
323 }
324
325 BOOST_UBLAS_INLINE
326 92200 array_type &data ()
327 {
328 92200 return data_;
329 }
330
331 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
332 class const_iterator:
333 public boost::numeric::ublas::container_const_reference<array_1d>,
334 public boost::numeric::ublas::random_access_iterator_base<boost::numeric::ublas::dense_random_access_iterator_tag,
335 const_iterator, value_type, difference_type>
336 {
337 public:
338 typedef boost::numeric::ublas::dense_random_access_iterator_tag iterator_category;
339 #ifdef BOOST_MSVC_STD_ITERATOR
340 typedef const_reference reference;
341 #else
342 typedef typename array_1d::difference_type difference_type;
343 typedef typename array_1d::value_type value_type;
344 typedef typename array_1d::const_reference reference;
345 typedef const typename array_1d::pointer pointer;
346 #endif
347
348 // Construction and destruction
349 BOOST_UBLAS_INLINE
350 const_iterator ():
351 boost::numeric::ublas::container_const_reference<self_type> (), it_ () {}
352 BOOST_UBLAS_INLINE
353 const_iterator (const self_type &v, const const_iterator_type &it):
354 boost::numeric::ublas::container_const_reference<self_type> (v), it_ (it) {}
355 BOOST_UBLAS_INLINE
356 #ifndef BOOST_UBLAS_QUALIFIED_TYPENAME
357 const_iterator (const iterator &it):
358 #else
359 const_iterator (const typename self_type::iterator &it):
360 #endif
361 boost::numeric::ublas::container_const_reference<self_type> (it ()), it_ (it.it_) {}
362
363 // Arithmetic
364 BOOST_UBLAS_INLINE
365 const_iterator &operator ++ ()
366 {
367 ++ it_;
368 return *this;
369 }
370 BOOST_UBLAS_INLINE
371 const_iterator &operator -- ()
372 {
373 -- it_;
374 return *this;
375 }
376 BOOST_UBLAS_INLINE
377 const_iterator &operator += (difference_type n)
378 {
379 it_ += n;
380 return *this;
381 }
382 BOOST_UBLAS_INLINE
383 const_iterator &operator -= (difference_type n)
384 {
385 it_ -= n;
386 return *this;
387 }
388 BOOST_UBLAS_INLINE
389 difference_type operator - (const const_iterator &it) const
390 {
391 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
392 return it_ - it.it_;
393 }
394
395 // Dereference
396 BOOST_UBLAS_INLINE
397 const_reference operator * () const
398 {
399 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, boost::numeric::ublas::bad_index ());
400 return *it_;
401 }
402
403 // Index
404 BOOST_UBLAS_INLINE
405 size_type index () const
406 {
407 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_, boost::numeric::ublas::bad_index ());
408 return it_ - (*this) ().begin ().it_;
409 }
410
411 // Assignment
412 BOOST_UBLAS_INLINE
413 const_iterator &operator = (const const_iterator &it)
414 {
415 boost::numeric::ublas::container_const_reference<self_type>::assign (&it ());
416 it_ = it.it_;
417 return *this;
418 }
419
420 // Comparison
421 BOOST_UBLAS_INLINE
422 bool operator == (const const_iterator &it) const
423 {
424 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
425 return it_ == it.it_;
426 }
427 BOOST_UBLAS_INLINE
428 bool operator < (const const_iterator &it) const
429 {
430 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
431 return it_ < it.it_;
432 }
433
434 private:
435 const_iterator_type it_;
436
437 friend class iterator;
438 };
439 #endif
440
441 #ifndef BOOST_UBLAS_USE_INDEXED_ITERATOR
442 class iterator:
443 public boost::numeric::ublas::container_reference<array_1d>,
444 public boost::numeric::ublas::random_access_iterator_base<boost::numeric::ublas::dense_random_access_iterator_tag,
445 iterator, value_type, difference_type>
446 {
447 public:
448 typedef boost::numeric::ublas::dense_random_access_iterator_tag iterator_category;
449 #ifndef BOOST_MSVC_STD_ITERATOR
450 typedef typename array_1d::difference_type difference_type;
451 typedef typename array_1d::value_type value_type;
452 typedef typename array_1d::reference reference;
453 typedef typename array_1d::pointer pointer;
454 #endif
455
456 // Construction and destruction
457 BOOST_UBLAS_INLINE
458 iterator ():
459 boost::numeric::ublas::container_reference<self_type> (), it_ () {}
460 BOOST_UBLAS_INLINE
461 iterator (self_type &v, const iterator_type &it):
462 boost::numeric::ublas::container_reference<self_type> (v), it_ (it) {}
463
464 // Arithmetic
465 BOOST_UBLAS_INLINE
466 iterator &operator ++ ()
467 {
468 ++ it_;
469 return *this;
470 }
471 BOOST_UBLAS_INLINE
472 iterator &operator -- ()
473 {
474 -- it_;
475 return *this;
476 }
477 BOOST_UBLAS_INLINE
478 iterator &operator += (difference_type n)
479 {
480 it_ += n;
481 return *this;
482 }
483 BOOST_UBLAS_INLINE
484 iterator &operator -= (difference_type n)
485 {
486 it_ -= n;
487 return *this;
488 }
489 BOOST_UBLAS_INLINE
490 difference_type operator - (const iterator &it) const
491 {
492 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
493 return it_ - it.it_;
494 }
495
496 // Dereference
497 BOOST_UBLAS_INLINE
498 reference operator * () const
499 {
500 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , boost::numeric::ublas::bad_index ());
501 return *it_;
502 }
503
504 // Index
505 BOOST_UBLAS_INLINE
506 size_type index () const
507 {
508 BOOST_UBLAS_CHECK (it_ >= (*this) ().begin ().it_ && it_ < (*this) ().end ().it_ , boost::numeric::ublas::bad_index ());
509 return it_ - (*this) ().begin ().it_;
510 }
511
512 // Assignment
513 BOOST_UBLAS_INLINE
514 iterator &operator = (const iterator &it)
515 {
516 boost::numeric::ublas::container_reference<self_type>::assign (&it ());
517 it_ = it.it_;
518 return *this;
519 }
520
521 // Comparison
522 BOOST_UBLAS_INLINE
523 bool operator == (const iterator &it) const
524 {
525 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
526 return it_ == it.it_;
527 }
528 BOOST_UBLAS_INLINE
529 bool operator < (const iterator &it) const
530 {
531 BOOST_UBLAS_CHECK (&(*this) () == &it (), boost::numeric::ublas::external_logic ());
532 return it_ < it.it_;
533 }
534
535 private:
536 iterator_type it_;
537
538 friend class const_iterator;
539 };
540 #endif
541
542
543 BOOST_UBLAS_INLINE
544 const_iterator begin () const
545 {
546 return find (0);
547 }
548 BOOST_UBLAS_INLINE
549 const_iterator end () const
550 {
551 return find (data_.size ());
552 }
553
554 BOOST_UBLAS_INLINE
555 iterator begin ()
556 {
557 return find (0);
558 }
559 BOOST_UBLAS_INLINE
560 iterator end ()
561 {
562 return find (data_.size ());
563 }
564
565 // Reverse iterator
566
567 #ifdef BOOST_MSVC_STD_ITERATOR
568 typedef reverse_iterator_base<const_iterator, value_type, const_reference> const_reverse_iterator;
569 #else
570 typedef boost::numeric::ublas::reverse_iterator_base<const_iterator> const_reverse_iterator;
571 #endif
572
573 BOOST_UBLAS_INLINE
574 const_reverse_iterator rbegin () const
575 {
576 return const_reverse_iterator (end ());
577 }
578 BOOST_UBLAS_INLINE
579 const_reverse_iterator rend () const
580 {
581 return const_reverse_iterator (begin ());
582 }
583
584 #ifdef BOOST_MSVC_STD_ITERATOR
585 typedef reverse_iterator_base<iterator, value_type, reference> reverse_iterator;
586 #else
587 typedef boost::numeric::ublas::reverse_iterator_base<iterator> reverse_iterator;
588 #endif
589
590 BOOST_UBLAS_INLINE
591 reverse_iterator rbegin ()
592 {
593 return reverse_iterator (end ());
594 }
595
596 BOOST_UBLAS_INLINE
597 reverse_iterator rend ()
598 {
599 return reverse_iterator (begin ());
600 }
601 ///@}
602 ///@name Inquiry
603 ///@{
604
605 ///@}
606 ///@name Input and output
607 ///@{
608
609 ///@}
610 ///@name Friends
611 ///@{
612
613 ///@}
614 protected:
615 ///@name Protected static Member Variables
616 ///@{
617
618 ///@}
619 ///@name Protected member Variables
620 ///@{
621
622 ///@}
623 ///@name Protected Operators
624 ///@{
625
626 ///@}
627 ///@name Protected Operations
628 ///@{
629
630 ///@}
631 ///@name Protected Access
632 ///@{
633
634 ///@}
635 ///@name Protected Inquiry
636 ///@{
637
638 ///@}
639 ///@name Protected LifeCycle
640 ///@{
641
642 ///@}
643 private:
644 ///@name Static Member Variables
645 ///@{
646
647 ///@}
648 ///@name Member Variables
649 ///@{
650
651 array_type data_; // The data contained
652
653 ///@}
654 ///@name Private Operators
655 ///@{
656
657 ///@}
658 ///@name Private Operations
659 ///@{
660
661 ///@}
662 ///@name Private Access
663 ///@{
664
665 ///@}
666 ///@name Private Inquiry
667 ///@{
668
669 ///@}
670 ///@name Un accessible methods
671 ///@{
672
673 ///@}
674
675 }; // Class array_1d
676
677 ///@}
678
679 ///@name Type Definitions
680 ///@{
681
682 ///@}
683 ///@name Input and output
684 ///@{
685
686 ///@}
687
688 } // namespace felisce.
689
690 #endif // FELISCE_ARRAY_1D_H_INCLUDED defined
691