import ceylon.language { 
    makeSpan=span, 
    makeMeasure=measure
}

"A range of adjacent [[Enumerable]] values. Two values of an
 enumerable type are considered _adjacent_ if their 
 [[offset|Enumerable.offset]] is of unit or zero magnitude. 
 Thus, a `Range` is a list of values where for every integer 
 `index` where both `index` and `index+1` fall within the 
 indices of the range:
 
     range[index+1].offset(range[index]).magnitude <= 1
 
 A range is always nonempty, containing at least one value.
 Thus, it is a [[Sequence]].
 
 A sequence of adjacent values may be represented very 
 efficiently in memory, either:
 
 - via its endpoints, `first..last`, or 
 - via an endpoint and length, `first:size`.
 
 Furthermore, certain operations are much more efficient 
 than for other lists, assuming that the enumerable type has 
 efficient [[neighbour|Enumerable.neighbour]] and
 [[offset|Enumerable.offset]] functions.
 
 The functions [[ceylon.language::span]] and 
 [[ceylon.language::measure]], and corresponding operators 
 `..` and `:` are used to create new instances of `Range`."
see (`function makeSpan`, 
     `function makeMeasure`)
shared sealed abstract class Range<Element>()
        of Span<Element> | Measure<Element>
        extends Object()  
        satisfies [Element+]
        given Element satisfies Enumerable<Element> {
    
	"Determines if this range includes the given value."
    shared formal Boolean containsElement(Element element);

	"Determines if this range includes the given range."
    shared formal Boolean includesRange(Range<Element> range);
	
	"Returns a range of the same length and type as this
	 range, with its endpoints shifted by the given number 
	 of elements, where:
	 
	 - a negative [[shift]] measures 
	   [[decrements|Ordinal.predecessor]], and 
	 - a positive `shift` measures 
	   [[increments|Ordinal.successor]]."
    shared formal Range<Element> shifted(Integer shift);
    
    "Determines if the range is increasing, that is, if
     successors occur after predecessors."
    shared formal Boolean increasing;
    
    "Determines if the range is decreasing, that is, if
     predecessors occur after successors."
    shared formal Boolean decreasing;
    
    "Returns the range itself, since a range cannot contain 
     null elements."
    shared actual Range<Element> coalesced => this;
    
}