Resize.hpp 3.55 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once

#include <dune/common/typeutilities.hh>

#include <amdis/common/ConceptsBase.hpp>
#include <amdis/common/Logical.hpp>

namespace AMDiS
{
  namespace Concepts
  {
    namespace Definition
    {
      struct VectorResizable
      {
        template <class V>
Praetorius, Simon's avatar
Praetorius, Simon committed
17
        auto require(V const& vec, Dune::PriorityTag<2>) -> decltype( const_cast<V&>(vec).resize(0u), 0);
18
19

        template <class V>
Praetorius, Simon's avatar
Praetorius, Simon committed
20
        auto require(V const& vec, Dune::PriorityTag<1>) -> decltype( const_cast<V&>(vec).change_dim(0u), 0);
21
22
23
24
25
      };

      struct MatrixResizable
      {
        template <class M>
Praetorius, Simon's avatar
Praetorius, Simon committed
26
        auto require(M const& mat, Dune::PriorityTag<3>) -> decltype( const_cast<M&>(mat).resize(0u,0u), 0);
27
28

        template <class M>
Praetorius, Simon's avatar
Praetorius, Simon committed
29
        auto require(M const& mat, Dune::PriorityTag<2>) -> decltype( const_cast<M&>(mat).change_dim(0u,0u), 0);
30
31

        template <class M>
Praetorius, Simon's avatar
Praetorius, Simon committed
32
        auto require(M const& mat, Dune::PriorityTag<1>) -> decltype( const_cast<M&>(mat).setSize(0u,0u), 0);
33
34
35
36
37
      };
    }

    /// Checks whether a vector can be resized by various resize methods
    template <class Vector>
Praetorius, Simon's avatar
Praetorius, Simon committed
38
    using VectorResizable_t = models_t<Definition::VectorResizable(Vector, Dune::PriorityTag<42>)>;
39
40
41

    /// Checks whether a matrix can be resized by various resize methods
    template <class Matrix>
Praetorius, Simon's avatar
Praetorius, Simon committed
42
    using MatrixResizable_t = models_t<Definition::MatrixResizable(Matrix, Dune::PriorityTag<42>)>;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

  } // end namespace Concepts

#ifdef DOXYGEN
  /// \brief Uniform vector resize, using either vector.resize() or vector.change_dim()
  template <class Vector>
  void resize(Vector& vec, std::size_t size);

  /// \brief Uniform matrix resize, using either matrix.resize(), matrix.setSize() or matrix.change_dim()
  template <class Matrix>
  void resize(Matrix& mat, std::size_t r, std::size_t c);
#else

  namespace Impl
  {
    template <class Vector,
      class = void_t<decltype(std::declval<Vector&>().resize(0u))> >
    void resize_impl(Vector& vec, std::size_t size, Dune::PriorityTag<2>)
    {
      vec.resize(size);
    }

    template <class Vector,
      class = void_t<decltype(std::declval<Vector&>().change_dim(0u))> >
    void resize_impl(Vector& vec, std::size_t size, Dune::PriorityTag<1>)
    {
      vec.change_dim(size);
    }

    template <class Vector>
    void resize_impl(Vector& /*vec*/, std::size_t /*size*/, Dune::PriorityTag<0>)
    {
      /* do nothing */
    }
  }

  template <class Vector>
  void resize(Vector& vec, std::size_t size)
  {
    Impl::resize_impl(vec, size, Dune::PriorityTag<42>{});
  }


  namespace Impl
  {
    template <class Matrix,
      class = void_t<decltype(std::declval<Matrix&>().resize(0u,0u))> >
    void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<3>)
    {
      mat.resize(rows, cols);
    }

    template <class Matrix,
      class = void_t<decltype(std::declval<Matrix&>().change_dim(0u,0u))> >
    void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<2>)
    {
      mat.change_dim(rows, cols);
    }

    template <class Matrix,
      class = void_t<decltype(std::declval<Matrix&>().setSize(0u,0u))> >
    void resize_impl(Matrix& mat, std::size_t rows, std::size_t cols, Dune::PriorityTag<1>)
    {
      mat.setSize(rows, cols);
    }

    template <class Matrix>
    void resize_impl(Matrix& /*mat*/, std::size_t /*rows*/, std::size_t /*cols*/, Dune::PriorityTag<0>)
    {
      /* do nothing */
    }
  }

  template <class Matrix>
  void resize(Matrix& mat, std::size_t rows, std::size_t cols)
  {
    Impl::resize_impl(mat, rows, cols, Dune::PriorityTag<42>{});
  }

#endif

} // end namespace AMDiS