Showing TypeFunction style

Stefan Koch uplink.coder at googlemail.com
Fri Oct 2 22:24:22 UTC 2020


Hi there,

This evening I played with a partial translation of 
implicitConversionTargets help in phobos.

Here is what I have so far.
Note that this is not true transliteration because I wanted to 
show some of the more unknown type function features.
---
alias Bool = bool;
alias Ubyte = ubyte;
alias Byte = byte;
alias Ushort = ushort;
alias Short = short;
alias Uint = uint;
alias Int = int;
alias Ulong = ulong;
alias Long = long;

// for those ty.isFloating is true, which takes a diffrent path 
than all other types ;)
// therefore we can't use it as of now
//alias Double = double;
//alias Float = float;

enum basic_types = makeAliasArray(Bool, Ubyte, Byte, Short, 
Ushort, Uint, Int, Long, Ulong, /*Double, Float*/);

// temporarly needed because parser issues ....
auto makeAliasArray(alias[] types ...)
{
     return types;
}

auto convTargets(alias T)
{
     if (isBasicType(T))
         return basicTypeConvTargets(T);
     return S.init;
}

bool isBasicType(alias T)
{
     foreach(t;basic_types)
     {
         if (is(T == t))
             return true;
     }
     return false;
}

// just showing off that you can store type arrays in structs
struct S
{
     typeof(makeAliasArray()) result;
     size_t n;
     alias type;
}

auto basicTypeConvTargets(alias T)
{
     typeof(makeAliasArray()) targets;
     targets.length = basic_types.length;
     assert(isBasicType(T), "You may not call this function when 
you don't have a basic type ... (given: " ~ T.stringof ~ ")");
     size_t n = 0;
     foreach(t;basic_types)
     {
         if (is(T : t))
         {
             targets[n++] = t;
         }
     }
     return S(targets[0 .. n], n, T);
}

pragma(msg, convTargets(Long));  // S([(long), (ulong)], 2LU, 
(long))
pragma(msg, convTargets(Short)); // S([(short), (ushort), (uint), 
(int), (long), (ulong)], 6LU, (short))

---

I hope that this code will be nice and readable.

As a comparison, here is a piece from the template I translated 
which should be equivalent.

---

     static if (is(T == bool))
         alias ImplicitConversionTargets =
             AliasSeq!(byte, ubyte, short, ushort, int, uint, 
long, ulong, CentTypeList,
                        float, double, real, char, wchar, dchar);
     else static if (is(T == byte))
         alias ImplicitConversionTargets =
             AliasSeq!(short, ushort, int, uint, long, ulong, 
CentTypeList,
                        float, double, real, char, wchar, dchar);
     else static if (is(T == ubyte))
         alias ImplicitConversionTargets =
             AliasSeq!(short, ushort, int, uint, long, ulong, 
CentTypeList,
                        float, double, real, char, wchar, dchar);
     else static if (is(T == short))
         alias ImplicitConversionTargets =
             AliasSeq!(int, uint, long, ulong, CentTypeList, 
float, double, real);
     else static if (is(T == ushort))
         alias ImplicitConversionTargets =
             AliasSeq!(int, uint, long, ulong, CentTypeList, 
float, double, real);
     else static if (is(T == int))
         alias ImplicitConversionTargets =
             AliasSeq!(long, ulong, CentTypeList, float, double, 
real);
     else static if (is(T == uint))
         alias ImplicitConversionTargets =
             AliasSeq!(long, ulong, CentTypeList, float, double, 
real);
     else static if (is(T == long))
         alias ImplicitConversionTargets = AliasSeq!(float, 
double, real);
     else static if (is(T == ulong))
         alias ImplicitConversionTargets = AliasSeq!(float, 
double, real);
---

The behavior is not 100% equivalent as the hand-written target 
list does not include signed conversions in the same size class. 
(I assume this is an omission).


Please leave comments and suggestions.



More information about the Digitalmars-d mailing list