Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 1741

Show
Ignore:
Timestamp:
07/09/10 04:18:41 (14 years ago)
Author:
andrei
Message:

Changed definition of isOutputRange and also added the free function put that effects outputting stuff to such a range.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/phobos/std/range.d

    r1734 r1741  
    218218        void popFront(); 
    219219        bool empty(); 
    220220        int front(); 
    221221    } 
    222222    static assert(isInputRange!(B)); 
    223223    static assert(isInputRange!(int[])); 
    224224    static assert(isInputRange!(char[])); 
    225225} 
    226226 
    227227/** 
    228 Returns $(D true) if $(D R) is an output range. An output range must 
    229 define the primitive $(D put) that accepts an object of type $(D 
    230 E). The following code should compile for any output range. 
    231  
    232 ---- 
    233 R r;             // can define a range object 
     228Returns $(D true) if $(D R) is an output range. An output range can be 
     229defined in two ways. 
     230 
     231$(OL $(LI $(D R) might define the primitive $(D put) that accepts an 
     232object convertible to $(D E). The following code should compile for 
     233such an output range: 
     234 
     235---- 
     236R r; 
    234237E e; 
    235238r.put(e);        // can write an element to the range 
    236239---- 
    237 The semantics of an output range (not checkable during compilation) 
    238 are assumed to be the following ($(D r) is an object of type $(D R)): 
    239  
    240 $(UL $(LI $(D r.put(e)) puts $(D e) in the range (in a range-dependent 
    241 manner) and advances to the popFront position in the range. Successive 
    242 calls to $(D r.put) add elements to the range. $(D put) may throw to 
    243 signal failure.)) 
     240 
     241The semantics of $(D r.put(e)) an output range (not checkable during 
     242compilation) are assumed to output $(D e) to $(D r) and advance to the 
     243next position in $(D r), such that successive calls to $(D r.put) add 
     244extra elements to $(D r).) 
     245 
     246$(LI An input range with assignable elements is also an output 
     247range. In that case, inserting elements into the range is effected 
     248with two primitive calls: $(D r.front = e, r.popFront()). Such a range 
     249functions for output only as long as it is not empty.)) 
     250 
     251To write elements to either kind of output range, call the free 
     252function $(D put(r, e)) defined below. That function takes the 
     253appropriate cource of action depending on the range's kind. 
    244254 */ 
    245255template isOutputRange(R, E) 
    246256{ 
    247257    enum bool isOutputRange = is(typeof( 
    248258    { 
    249259        R r;            // can define a range object 
    250260        E e; 
    251261        r.put(e);       // can write element to range 
     262    }())) || isInputRange!R && is(typeof( 
     263    { 
     264        R r;               // can define a range object 
     265        E e; 
     266        r.front = e;       // can assign to the front of range 
    252267    }())); 
     268} 
     269 
     270/** 
     271Outputs $(D e) to $(D r), which must be an output range. Depending on 
     272the range's kind, it either evaluates $(D r.put(e)) or $(D (r.front = 
     273e, r.popFront())). 
     274 */ 
     275void put(R, E)(ref R r, E e) if (isOutputRange!(R, E)) 
     276{ 
     277    static if (is(typeof(&r.put))) 
     278    { 
     279        r.put(e); 
     280    } 
     281    else 
     282    { 
     283        r.front = e; 
     284        r.popFront(); 
     285    } 
    253286} 
    254287 
    255288unittest 
    256289{ 
    257290    struct A {} 
    258291    static assert(!isInputRange!(A)); 
    259292    struct B 
    260293    { 
    261294        void put(int); 
    262295    }