C++ Logo

std-discussion

Advanced search

2 big problems with User Defined literals:

From: Andy Little <kwikius_at_[hidden]>
Date: Thu, 6 May 2021 13:09:52 +0000 (UTC)
2 big problems with User Defined literals:

1)

   Why can't user defined literals have a namespace prefix?...............................................................................................

I have a units library I have used for many years.

I would prefer to be able to say

auto x = pqs::1_m; // x is a physical quantity representing 1 meter

Then I could also make use of other units libraries in the same application. As it stands, if another units library also defines its own UDLs' in its headers then it will be very difficult to work with it.

-------------------------

2)
Clumsy handling of the types returned want smallest, not biggest
.............................................................
Other issue with user defined literals is their use of unsigned long long and long double. This can cause unnecessary narrowing conversion warnings since the biggest possible types end up being used. Exact opposite to what you want , (especially on a microcontroller) so now you need add ugly conversions everywhere. It would be nice to be able to tailor the return type depending on the value to the smallest type that fits. This could be done so easily if the value was made available to the UDL function ( e.g like a template parameter ) for example:

```c++

#include <limits>
#include <type_traits>

//see https://github.com/kwikius/pqs
#include <pqs/bits/meta/eval_if.hpp>
#include <pqs/bits/meta/identity.hpp>
#include <pqs/bits/meta/is_narrowing_conversion.hpp>

namespace meta = pqs::meta;

template <typename T>
struct my_type{
   constexpr my_type( T const & v): val{v}{}
   T val;

   template <typename T1>
   //https://github.com/kwikius/pqs/blob/master/src/include/pqs/bits/meta/is_narrowing_conversion.hpp
   // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p0870r4.html
      requires !meta::is_narrowing_conversion<T, T1>
   constexpr operator my_type<T1>() const { return {val};}
};

struct undefined;

/*
  return type of min sized int that can hold V
*/
template <unsigned long long V>
struct min_int{

   // https://github.com/kwikius/pqs/blob/master/src/include/pqs/bits/meta/eval_if.hpp
   // eval_if return the first member type of element after the first true condition
   // or last element
   typedef typename meta::eval_if<
         std::integral_constant<bool,(V < static_cast<unsigned long long>(std::numeric_limits<int8_t>::max()))>,
      meta::identity<int8_t>, // https://github.com/kwikius/pqs/blob/master/src/include/pqs/bits/meta/identity.hpp
         std::integral_constant<bool,(V < static_cast<unsigned long long>(std::numeric_limits<int16_t>::max()))>,
      meta::identity<int16_t>,
         std::integral_constant<bool,(V < static_cast<unsigned long long>(std::numeric_limits<int32_t>::max()))>,
      meta::identity<int32_t>,
         std::integral_constant<bool,(V < static_cast<unsigned long long>(std::numeric_limits<int64_t>::max()))>,
      meta::identity<int64_t>,
      undefined
>::type type;
};

template <unsigned long long V>
using min_int_t = typename min_int<V>::type;

/*
##########################################################################So Really want a UDL here
I can easily tailor return type dependent on V but not with a UDL since value of V is not available!!!
------------------------------------------------------------------------
*/
template <unsigned long long V>
constexpr my_type<min_int_t<V> > my_type_udl()
{
   return {V};
}
//#################################################

int main()
{
   auto x = my_type_udl<1>();
   auto constexpr y = my_type_udl<0x1fff>();
   auto z = my_type_udl<0xffff>();

   static_assert(std::is_same<decltype(x),my_type<int8_t> >::value,"");
   static_assert(std::is_same<decltype(y),my_type<int16_t> const >::value,"");
   static_assert(std::is_same<decltype(z),my_type<int32_t> >::value,"");

   z = x; // OK
   z = y; // Great!
  //#######################################
   x = z; // Error thank you for catching that!
  //######################################
   
}
```







Received on 2021-05-06 08:10:06