Range non-emptyness assertions and opIndex

Nordlöw via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jul 1 03:35:04 PDT 2016


If I have a typical range definition like the following

     struct Range
     {
         @safe pure @nogc:

         bool empty() const nothrow
         {
             return _i == _j;
         }

         size_t length() const nothrow
         {
             return _j - _i;
         }

         bool front() const
         {
             assert(!empty);     // TODO use enforce when it's 
@nogc
             return _store[_i];
         }

         bool back() const
         {
             assert(!empty);     // TODO use enforce when it's 
@nogc
             return _store[_j - 1];
         }

         void popFront()
         {
             assert(!empty);
             ++_i;
         }

         void popBack()
         {
             assert(!empty);
             ++_i;
         }

     private:
         BitSet _store;          // copy of store
         size_t _i = 0;         // iterator into _store
         size_t _j = _store.length;
     }

What's the preferred way of reacting to emptyness in the members 
front, back, popFront, popBack --- using assert, enforce, throw, 
or simply relying on range-checking in the _store?

And what about using

     debug assert()

instead of

     assert()

typically when `_store`s `opIndex` already performs 
range-checking?

I think this is a important issue since asserts are not optimized 
away in release mode and D is very much about performance.


More information about the Digitalmars-d-learn mailing list