New to D and mimicking C++ : how to implement std::integral_constant<>?

Picaud Vincent via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Nov 7 15:03:32 PST 2016


On Monday, 7 November 2016 at 22:18:56 UTC, Jerry wrote:
> On Monday, 7 November 2016 at 21:37:50 UTC, Picaud Vincent 
> wrote:
>>>   static if ( isIntegralConstant!(typeof(required_capacity()) 
>>> )
>>> {
>>> }
>>> else
>>> {
>>> }
>>>
>>> }
>>
>> Premature post send by error sorry.... Well something like:
>>
>>    static if ( isIntegralConstant!(typeof(required_capacity()) 
>> )
>>      ElementType[required_capacity()] data_;
>>    else
>>      ElementType[] data_;
>> }
>>
>> For that, at least in C++, I need integral_constant<> type 
>> with compile-time arithmetic and smooth integration with 
>> "usual" size_t/ptrdiff_t types.
>>
>> 2/ I also would like to test some implementations concerning 
>> automatic differentiation.
>> I have my own C++ libs, inspired, but ~20% faster than Adept:
>> http://www.met.reading.ac.uk/clouds/adept/
>> and I would like to know how I can do that in D
>>
>> Well... That is the idea... I hope I will get some results and 
>> I will be happy to share if it is something interesting.
>>
>> Vincent
>
> Ah I get what you mean, you can do that without using a special 
> type.
>
>     struct Vector(T, Args...) if(Args.length == 1)
>     {
>         static if(is(Args[0] == size_t))
>         {
>             size_t size;
>         }
>         else static if(Args[0] != 0) // would error if it's a 
> type that's not size_t
>         {
>             enum size = Args[0];
>         }
>         else
>         {
>             static assert(0);
>         }
>     }
>
>     Vector!(int, 10) a;
>     Vector!(int, size_t) b; // both work with IntegralConstant
>
> could use __traits(compiles) to see if it's not a type, for 
> that second static if. Which would probably be better, so if 
> you pass a float or something, it won't give a weird error.

Thank you again Jerry!

For sure my way of thinking is twisted by my C++ habits! :-/

The positive point is that D seems to offer much shorter 
solutions (this is my hope).

However I still need some investigations and/or some guidance:

-> not sure that it is ok for me as I really want to track 
"static constants" all the
    way long.
    That is the reason why I introduced the IntegralConstant type
    (with operator overloading, work in progress)

For instance, the code:

  enum int a=1,b=2;
  auto c = a+b;

  pragma(msg,typeof(c));   // prints "int"
  static assert(c==3);     // compilation fails: "variable c 
cannot be read at compile time"

To implement my vector structs I need:

1/ a way to detect compile-time constant vs "dynamic" values
2/ to perform and to propagate compile-time constants across 
"arithmetic" computations.
    For instance to compute the required capacity to store vector 
data, I need something
like

auto capacity = max(0,(size_-1)*stride_);

and this expression must make sense for both "dynamic" values and 
compile-time constant.

In one case I expect
    typeof(capacity) -> int,
in the other
    typeof(capacity) -> IntegralConst



More information about the Digitalmars-d-learn mailing list