Templates class member functions not conditional?

bearophile bearophileHUGS at lycos.com
Tue Sep 11 06:33:36 PDT 2012


monarch_dodra:

> and forces the implementer to think about the required 
> conditions to use the function,

I think this is usually considered a good practice in D, just 
like using template constraints.

If you look in Phobos, similar situations are handled with static 
ifs. As example see the several static if used inside MapResult() 
to disable some of its features:

https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L384


private struct MapResult(alias fun, Range)
{
     alias Unqual!Range R;
     //alias typeof(fun(.ElementType!R.init)) ElementType;
     R _input;

     static if (isBidirectionalRange!R)
     {
         @property auto ref back()
         {
             return fun(_input.back);
         }

         void popBack()
         {
             _input.popBack();
         }
     }

     this(R input)
     {
         _input = input;
     }

     static if (isInfinite!R)
     {
         // Propagate infinite-ness.
         enum bool empty = false;
     }
     else
     {
         @property bool empty()
         {
             return _input.empty;
         }
     }

     void popFront()
     {
         _input.popFront();
     }

     @property auto ref front()
     {
         return fun(_input.front);
     }

     static if (isRandomAccessRange!R)
     {
         static if (is(typeof(_input[ulong.max])))
             private alias ulong opIndex_t;
         else
             private alias uint opIndex_t;

         auto ref opIndex(opIndex_t index)
         {
             return fun(_input[index]);
         }
     }

     static if (hasLength!R || isSomeString!R)
     {
         @property auto length()
         {
             return _input.length;
         }

         alias length opDollar;
     }

     static if (hasSlicing!R)
     {
         static if (is(typeof(_input[ulong.max .. ulong.max])))
             private alias ulong opSlice_t;
         else
             private alias uint opSlice_t;

         auto opSlice(opSlice_t lowerBound, opSlice_t upperBound)
         {
             return typeof(this)(_input[lowerBound..upperBound]);
         }
     }

     static if (isForwardRange!R)
     {
         @property auto save()
         {
             auto result = this;
             result._input = result._input.save;
             return result;
         }
     }
}


Bye,
bearophile


More information about the Digitalmars-d-learn mailing list