Skip to content
Snippets Groups Projects
Commit c2881917 authored by Simon Praetorius's avatar Simon Praetorius
Browse files

Add user-defined literal to represent index_constants

parent 384faac1
No related branches found
No related tags found
1 merge request!1077Add user-defined literal to represent index_constants
......@@ -43,6 +43,8 @@ In order to build the DUNE core modules you need at least the following software
- The storage type `ReservedVector` is extended to follow more closely the `std::vector` and
`std::array` interfaces.
- Add user-defined literals `_uc` and `_sc` to represent integer constants.
## Build System
- Improve the the function `dune_add_library` by separating the target types normal, interface, and
......
......@@ -7,6 +7,7 @@
#define DUNE_COMMON_INDICES_HH
#include <cstddef>
#include <stdexcept>
#include <type_traits>
#include <utility>
......@@ -127,6 +128,92 @@ namespace Dune
return f(std::integral_constant<I, i>()...);
}
namespace Indices::Literals
{
namespace Impl
{
// convert a single character into an unsigned integer
constexpr unsigned char2digit (const char c)
{
if (c >= '0' && c <= '9')
return unsigned(c) - unsigned('0');
else {
throw std::invalid_argument("Character is not a digit.");
return 0u;
}
}
// convert a sequence of character digits into an unsigned integer
template <class T, char... digits>
constexpr T chars2unsigned ()
{
const char arr[] = {digits...};
if (arr[0] == '-')
throw std::invalid_argument("Negative index constant not allowed.");
T result = 0;
T power = 1;
const T base = 10;
const int N = sizeof...(digits);
for (int i = 0; i < N; ++i) {
char c = arr[N - 1 - i];
result+= char2digit(c) * power;
power *= base;
}
return result;
}
// convert a sequence of character digits into a signed integer
template <class T, char digit0, char... digits>
constexpr T chars2signed ()
{
return digit0 == '-'
? -chars2unsigned<T,digits...>()
: chars2unsigned<T,digit0,digits...>();
}
} //namespace Impl
/**
* \brief Literal to create an index compile-time constant
*
* \b Example:
* `1_ic -> std::integral_constant<std::size_t,1>`
**/
template <char... digits>
constexpr auto operator"" _ic()
{
return std::integral_constant<std::size_t, Impl::chars2unsigned<std::size_t,digits...>()>{};
}
/**
* \brief Literal to create an unsigned integer compile-time constant
*
* \b Example:
* `1_uc -> std::integral_constant<unsigned,1>`
**/
template <char... digits>
constexpr auto operator"" _uc()
{
return std::integral_constant<unsigned, Impl::chars2unsigned<unsigned,digits...>()>{};
}
/**
* \brief Literal to create a signed integer compile-time constant
*
* \b Example:
* `-1_sc -> std::integral_constant<int,-1>`
**/
template <char... digits>
constexpr auto operator"" _sc()
{
return std::integral_constant<int, Impl::chars2signed<int,digits...>()>{};
}
} //namespace Indices::Literals
} //namespace Dune
#endif // DUNE_COMMON_INDICES_HH
......@@ -30,5 +30,23 @@ int main()
std::get<_1>(v) = 4.14;
std::get<_2>(v) = 3.7;
{ // test user-defined literal _xc
using namespace Dune::Indices::Literals;
static_assert(_0 == 0_ic);
static_assert(_1 == 1_ic);
static_assert(_2 == 2_ic);
static_assert(_3 == 3_ic);
static_assert(_4 == 4_ic);
static_assert(_5 == 5_ic);
static_assert(_6 == 6_ic);
static_assert(_7 == 7_ic);
static_assert(_8 == 8_ic);
static_assert(_9 == 9_ic);
static_assert(123_uc == 123u);
static_assert(-123_sc == -123);
}
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment