Changeset 1741
- Timestamp:
- 07/09/10 04:18:41 (14 years ago)
- Files:
-
- trunk/phobos/std/range.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/phobos/std/range.d
r1734 r1741 218 218 void popFront(); 219 219 bool empty(); 220 220 int front(); 221 221 } 222 222 static assert(isInputRange!(B)); 223 223 static assert(isInputRange!(int[])); 224 224 static assert(isInputRange!(char[])); 225 225 } 226 226 227 227 /** 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 228 Returns $(D true) if $(D R) is an output range. An output range can be 229 defined in two ways. 230 231 $(OL $(LI $(D R) might define the primitive $(D put) that accepts an 232 object convertible to $(D E). The following code should compile for 233 such an output range: 234 235 ---- 236 R r; 234 237 E e; 235 238 r.put(e); // can write an element to the range 236 239 ---- 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 241 The semantics of $(D r.put(e)) an output range (not checkable during 242 compilation) are assumed to output $(D e) to $(D r) and advance to the 243 next position in $(D r), such that successive calls to $(D r.put) add 244 extra elements to $(D r).) 245 246 $(LI An input range with assignable elements is also an output 247 range. In that case, inserting elements into the range is effected 248 with two primitive calls: $(D r.front = e, r.popFront()). Such a range 249 functions for output only as long as it is not empty.)) 250 251 To write elements to either kind of output range, call the free 252 function $(D put(r, e)) defined below. That function takes the 253 appropriate cource of action depending on the range's kind. 244 254 */ 245 255 template isOutputRange(R, E) 246 256 { 247 257 enum bool isOutputRange = is(typeof( 248 258 { 249 259 R r; // can define a range object 250 260 E e; 251 261 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 252 267 }())); 268 } 269 270 /** 271 Outputs $(D e) to $(D r), which must be an output range. Depending on 272 the range's kind, it either evaluates $(D r.put(e)) or $(D (r.front = 273 e, r.popFront())). 274 */ 275 void 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 } 253 286 } 254 287 255 288 unittest 256 289 { 257 290 struct A {} 258 291 static assert(!isInputRange!(A)); 259 292 struct B 260 293 { 261 294 void put(int); 262 295 }
