Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
amdis-core
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
External wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
amdis
amdis-core
Commits
989b5b7c
Commit
989b5b7c
authored
5 years ago
by
Praetorius, Simon
Browse files
Options
Downloads
Patches
Plain Diff
added backport of transformedRangeView from dune-2.7 git branch
parent
10aab891
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/amdis/utility/CMakeLists.txt
+1
-0
1 addition, 0 deletions
src/amdis/utility/CMakeLists.txt
src/amdis/utility/MappedRangeView.hpp
+467
-0
467 additions, 0 deletions
src/amdis/utility/MappedRangeView.hpp
with
468 additions
and
0 deletions
src/amdis/utility/CMakeLists.txt
+
1
−
0
View file @
989b5b7c
...
...
@@ -3,6 +3,7 @@ install(FILES
LocalBasisCache.hpp
LocalToGlobalAdapter.hpp
MacroGridFactory.hpp
MappedRangeView.hpp
QuadratureFactory.hpp
Twist.hpp
UniqueBorderPartition.hpp
...
...
This diff is collapsed.
Click to expand it.
src/amdis/utility/MappedRangeView.hpp
0 → 100644
+
467
−
0
View file @
989b5b7c
#pragma once
#include
<iterator>
#include
<type_traits>
#include
<amdis/common/TypeTraits.hpp>
namespace
AMDiS
{
// NOTE: this is a backport of the dune-common TransformedRangeView with added size() function.
namespace
Impl
{
// Helper class to mimic a pointer for proxy objects.
// This is needed to implement operator-> on an iterator
// using proxy-values. It stores the proxy value but
// provides operator-> like a pointer.
template
<
class
ProxyType
>
class
PointerProxy
{
public:
PointerProxy
(
ProxyType
&&
p
)
:
p_
(
p
)
{}
ProxyType
*
operator
->
()
{
return
&
p_
;
}
ProxyType
p_
;
};
// An iterator transforming a wrapped iterator using
// an unary function. It inherits the iterator-category
// of the underlying iterator.
template
<
class
I
,
class
F
,
class
C
=
typename
std
::
iterator_traits
<
I
>
::
iterator_category
>
class
MappedRangeIterator
;
template
<
class
I
,
class
F
>
class
MappedRangeIterator
<
I
,
F
,
std
::
forward_iterator_tag
>
{
public:
using
iterator_category
=
std
::
forward_iterator_tag
;
using
reference
=
decltype
(
std
::
declval
<
F
>
()(
*
(
std
::
declval
<
I
>
())));
using
value_type
=
std
::
decay_t
<
reference
>
;
using
pointer
=
PointerProxy
<
value_type
>
;
// If we later want to allow standalone MappedRangeIterators,
// we could customize the FunctionPointer to be a default-constructible,
// copy-assignable type storing a function but acting like a pointer
// to function.
using
FunctionPointer
=
const
F
*
;
constexpr
MappedRangeIterator
(
const
I
&
it
,
FunctionPointer
f
)
noexcept
:
it_
(
it
)
,
f_
(
f
)
{}
// Explicitly initialize members. Using a plain
//
// constexpr MappedRangeIterator() noexcept {}
//
// would default-initialize the members while
//
// constexpr MappedRangeIterator() noexcept : it_(), f_() {}
//
// leads to value-initialization. This is a case where
// both are really different. If it_ is a raw pointer (i.e. POD)
// then default-initialization leaves it uninitialized while
// value-initialization zero-initializes it.
constexpr
MappedRangeIterator
()
noexcept
:
it_
()
,
f_
()
{}
// Dereferencing returns a value created by the function
constexpr
reference
operator
*
()
const
noexcept
{
return
(
*
f_
)(
*
it_
);
}
// Dereferencing returns a value created by the function
pointer
operator
->
()
const
noexcept
{
return
(
*
f_
)(
*
it_
);
}
constexpr
MappedRangeIterator
&
operator
=
(
MappedRangeIterator
const
&
)
=
default
;
constexpr
bool
operator
==
(
const
MappedRangeIterator
&
other
)
const
noexcept
{
return
(
it_
==
other
.
it_
);
}
constexpr
bool
operator
!=
(
const
MappedRangeIterator
&
other
)
const
noexcept
{
return
(
it_
!=
other
.
it_
);
}
MappedRangeIterator
&
operator
++
()
noexcept
{
++
it_
;
return
*
this
;
}
MappedRangeIterator
operator
++
(
int
)
noexcept
{
MappedRangeIterator
copy
(
*
this
);
++
(
*
this
);
return
copy
;
}
protected
:
I
it_
;
FunctionPointer
f_
;
};
template
<
class
I
,
class
F
>
class
MappedRangeIterator
<
I
,
F
,
std
::
bidirectional_iterator_tag
>
:
public
MappedRangeIterator
<
I
,
F
,
std
::
forward_iterator_tag
>
{
protected:
using
Base
=
MappedRangeIterator
<
I
,
F
,
std
::
forward_iterator_tag
>
;
using
Base
::
it_
;
using
Base
::
f_
;
public:
using
iterator_category
=
std
::
bidirectional_iterator_tag
;
using
reference
=
typename
Base
::
reference
;
using
value_type
=
typename
Base
::
value_type
;
using
pointer
=
typename
Base
::
pointer
;
using
FunctionPointer
=
typename
Base
::
FunctionPointer
;
// inheriting constructor
using
Base
::
Base
;
// Member functions of the forward_iterator that need
// to be redefined because the base class methods return a
// forward_iterator.
constexpr
MappedRangeIterator
&
operator
=
(
MappedRangeIterator
const
&
)
=
default
;
MappedRangeIterator
&
operator
++
()
noexcept
{
++
it_
;
return
*
this
;
}
MappedRangeIterator
operator
++
(
int
)
noexcept
{
MappedRangeIterator
copy
(
*
this
);
++
(
*
this
);
return
copy
;
}
// Additional member functions of bidirectional_iterator
MappedRangeIterator
&
operator
--
()
noexcept
{
--
(
this
->
it_
);
return
*
this
;
}
MappedRangeIterator
operator
--
(
int
)
noexcept
{
MappedRangeIterator
copy
(
*
this
);
--
(
*
this
);
return
copy
;
}
};
template
<
class
I
,
class
F
>
class
MappedRangeIterator
<
I
,
F
,
std
::
random_access_iterator_tag
>
:
public
MappedRangeIterator
<
I
,
F
,
std
::
bidirectional_iterator_tag
>
{
protected:
using
Base
=
MappedRangeIterator
<
I
,
F
,
std
::
bidirectional_iterator_tag
>
;
using
Base
::
it_
;
using
Base
::
f_
;
public:
using
iterator_category
=
std
::
random_access_iterator_tag
;
using
reference
=
typename
Base
::
reference
;
using
value_type
=
typename
Base
::
value_type
;
using
pointer
=
typename
Base
::
pointer
;
using
difference_type
=
typename
std
::
iterator_traits
<
I
>::
difference_type
;
using
FunctionPointer
=
typename
Base
::
FunctionPointer
;
// inheriting constructor
using
Base
::
Base
;
// Member functions of the forward_iterator that need
// to be redefined because the base class methods return a
// forward_iterator.
constexpr
MappedRangeIterator
&
operator
=
(
MappedRangeIterator
const
&
)
=
default
;
MappedRangeIterator
&
operator
++
()
noexcept
{
++
it_
;
return
*
this
;
}
MappedRangeIterator
operator
++
(
int
)
noexcept
{
MappedRangeIterator
copy
(
*
this
);
++
(
*
this
);
return
copy
;
}
// Member functions of the bidirectional_iterator that need
// to be redefined because the base class methods return a
// bidirectional_iterator.
MappedRangeIterator
&
operator
--
()
noexcept
{
--
(
this
->
it_
);
return
*
this
;
}
MappedRangeIterator
operator
--
(
int
)
noexcept
{
MappedRangeIterator
copy
(
*
this
);
--
(
*
this
);
return
copy
;
}
// Additional member functions of random_access_iterator
MappedRangeIterator
&
operator
+=
(
difference_type
n
)
noexcept
{
it_
+=
n
;
return
*
this
;
}
MappedRangeIterator
&
operator
-=
(
difference_type
n
)
noexcept
{
it_
-=
n
;
return
*
this
;
}
bool
operator
<
(
const
MappedRangeIterator
&
other
)
noexcept
{
return
it_
<
other
.
it_
;
}
bool
operator
<=
(
const
MappedRangeIterator
&
other
)
noexcept
{
return
it_
<=
other
.
it_
;
}
bool
operator
>
(
const
MappedRangeIterator
&
other
)
noexcept
{
return
it_
>
other
.
it_
;
}
bool
operator
>=
(
const
MappedRangeIterator
&
other
)
noexcept
{
return
it_
>=
other
.
it_
;
}
reference
operator
[](
difference_type
n
)
noexcept
{
return
(
*
f_
)(
*
(
it_
+
n
));
}
friend
MappedRangeIterator
operator
+
(
const
MappedRangeIterator
&
it
,
difference_type
n
)
noexcept
{
return
MappedRangeIterator
(
it
.
it_
+
n
,
it
.
f_
);
}
friend
MappedRangeIterator
operator
+
(
difference_type
n
,
const
MappedRangeIterator
&
it
)
noexcept
{
return
MappedRangeIterator
(
n
+
it
.
it_
,
it
.
f_
);
}
friend
MappedRangeIterator
operator
-
(
const
MappedRangeIterator
&
it
,
difference_type
n
)
noexcept
{
return
MappedRangeIterator
(
it
.
it_
-
n
,
it
.
f_
);
}
friend
difference_type
operator
-
(
const
MappedRangeIterator
&
first
,
const
MappedRangeIterator
&
second
)
noexcept
{
return
first
.
it_
-
second
.
it_
;
}
};
}
// namespace Impl
/**
* \brief A range transforming the values of another range on-the-fly
*
* This behaves like a range providing `begin()` and `end()`.
* The iterators over this range internally iterate over
* the wrapped range. When dereferencing the iterator,
* the value is transformed on-the-fly using a given
* transformation function leaving the underlying range
* unchanged.
*
* The transformation may either return temorary values
* or l-value references. In the former case the range behaves
* like a proxy-container. In the latter case it forwards these
* references allowing, e.g., to sort a subset of some container
* by applying a transformation to an index-range for those values.
*
* The iterators of the MappedRangeView have the same
* iterator_category as the ones of the wrapped container.
*
* If range is given as r-value, then the returned MappedRangeView
* stores it by value, if range is given as (const) l-value, then the
* MappedRangeView stores it by (const) reference.
*
* If R is a value type, then the MappedRangeView stores the wrapped range by value,
* if R is a reference type, then the MappedRangeView stores the wrapped range by reference.
*
* \tparam R Underlying range.
* \tparam F Unary function used to transform the values in the underlying range.
**/
template
<
class
R
,
class
F
>
class
MappedRangeView
{
using
RawConstIterator
=
TYPEOF
(
std
::
declval
<
const
R
>
().
begin
());
using
RawIterator
=
TYPEOF
(
std
::
declval
<
R
>
().
begin
());
public:
/**
* \brief Iterator type
*
* This inherits the iterator_category of the iterators
* of the underlying range.
*/
using
const_iterator
=
Impl
::
MappedRangeIterator
<
RawConstIterator
,
F
>
;
using
iterator
=
Impl
::
MappedRangeIterator
<
RawIterator
,
F
>
;
/**
* \brief Construct from range and function
*/
template
<
class
RR
>
constexpr
MappedRangeView
(
RR
&&
rawRange
,
F
const
&
f
)
noexcept
:
rawRange_
(
FWD
(
rawRange
))
,
f_
(
f
)
{}
/**
* \brief Obtain a iterator to the first element
*
* The life time of the returned iterator is bound to
* the life time of the range since it only contains a
* pointer to the transformation function stored
* in the range.
*/
constexpr
const_iterator
begin
()
const
noexcept
{
return
const_iterator
(
rawRange_
.
begin
(),
&
f_
);
}
constexpr
iterator
begin
()
noexcept
{
return
iterator
(
rawRange_
.
begin
(),
&
f_
);
}
/**
* \brief Return the number of elements in the range, if availble.
*
* Note, this function is only availble if the underlying raw range
* knows its size and provides a function `size()`.
*/
template
<
class
RR
=
R
,
class
=
decltype
(
std
::
declval
<
RR
>().
size
())
>
constexpr
auto
size
()
const
noexcept
{
return
rawRange_
.
size
();
}
/// Provide element access for random-accessible ranges
template
<
class
RR
=
R
,
class
=
decltype
(
std
::
declval
<
RR
>().
operator
[](
std
::
size_t
(
0
)))
>
decltype
(
auto
)
operator
[](
std
::
size_t
i
)
const
{
return
f_
(
rawRange_
[
i
]);
}
/**
* \brief Checks whether the range is empty
*/
constexpr
bool
empty
()
const
noexcept
{
return
rawRange_
.
begin
()
==
rawRange_
.
end
();
}
/**
* \brief Obtain a iterator past the last element
*
* The life time of the returned iterator is bound to
* the life time of the range since it only contains a
* pointer to the transformation function stored
* in the range.
*/
constexpr
const_iterator
end
()
const
noexcept
{
return
const_iterator
(
rawRange_
.
end
(),
&
f_
);
}
constexpr
iterator
end
()
noexcept
{
return
iterator
(
rawRange_
.
end
(),
&
f_
);
}
private
:
R
rawRange_
;
F
f_
;
};
/**
* \brief Create a MappedRangeView
*
* \param range The range the transform
* \param f Unary function that should the applied to the entries of the range.
*
* This behaves like a range providing `begin()` and `end()`.
* The iterators over this range internally iterate over
* the wrapped range. When dereferencing the iterator,
* the value is transformed on-the-fly using a given
* transformation function leaving the underlying range
* unchanged.
*
* The transformation may either return temporary values
* or l-value references. In the former case the range behaves
* like a proxy-container. In the latter case it forwards these
* references allowing, e.g., to sort a subset of some container
* by applying a transformation to an index-range for those values.
*
* The iterators of the MappedRangeView have the same
* iterator_category as the ones of the wrapped container.
*
* If range is an r-value, then the MappedRangeView stores it by value,
* if range is an l-value, then the MappedRangeView stores it by reference.
**/
template
<
class
R
,
class
F
>
auto
mappedRangeView
(
R
&&
range
,
F
const
&
f
)
{
return
MappedRangeView
<
R
,
F
>
(
FWD
(
range
),
f
);
}
template
<
class
Iter
,
class
F
>
auto
mappedIterator
(
Iter
it
,
F
const
*
f
)
{
using
iterator
=
Impl
::
MappedRangeIterator
<
Iter
,
F
>
;
return
iterator
(
it
,
f
);
}
template
<
class
ConstIter
,
class
F
>
auto
mappedConstIterator
(
ConstIter
it
,
F
const
*
f
)
{
using
const_iterator
=
Impl
::
MappedRangeIterator
<
ConstIter
,
F
>
;
return
const_iterator
(
it
,
f
);
}
}
// end namespace AMDiS
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment