type Ordering = (_EQ, _LT, _GT); IEq = interface function eequal(x, y: T): boolean; function notEqual(x, y: T): boolean; end; Eq = abstract class(IEq) public function eequal(x, y: T): boolean; virtual; begin Result := not notEqual(x, y); end; function notEqual(x, y: T): boolean; virtual; begin Result := not eequal(x, y); end; end; IOrd = interface(IEq) function compare(x, y: T): Ordering; function less(x, y: T): boolean; function lessEqual(x, y: T): boolean; function greater(x, y: T): boolean; function greaterEqual(x, y: T): boolean; function mmin(x, y: T): T; function mmax(x, y: T): T; end; Ord = abstract class(IOrd) where EqT: IEq, constructor; public function compare(x, y: T): Ordering; virtual; begin var eqInst := __ConceptSingleton&.&Instance; if eqInst.eequal(x, y) then Result := _EQ else if less(x, y) then Result := _LT else Result := _GT; end; function less(x, y: T): boolean; virtual; begin Result := compare(x, y) = _LT; end; function lessEqual(x, y: T): boolean; virtual; begin Result := compare(x, y) <> _GT; end; function greater(x, y: T): boolean; virtual; begin Result := compare(x, y) = _GT; end; function greaterEqual(x, y: T): boolean; virtual; begin Result := compare(x, y) <> _LT; end; function mmin(x, y: T): T; virtual; begin Result := lessEqual(x, y) ? x : y; end; function mmax(x, y: T): T; virtual; begin Result := lessEqual(x, y) ? y : x; end; function eequal(x, y: T): boolean; virtual; begin var eqInst := __ConceptSingleton&.&Instance; Result := eqInst.eequal(x, y); end; function notEqual(x, y: T): boolean; virtual; begin var eqInst := __ConceptSingleton&.&Instance; Result := eqInst.notEqual(x, y); end; end; Eq_integer = class(Eq, IEq) public function eequal(x, y: integer): boolean; override; begin Result := x = y; end; end; Ord_integer = class(Ord, IOrd) where EqT: IEq, constructor; public function compare(x, y: integer): Ordering; override; begin if self.eequal(x, y) then Result := _EQ else if x < y then Result := _LT else Result := _GT; end; end; function Max3(v1, v2, v3: T): T; where OrdT: IOrd, constructor; begin var ordInst := __ConceptSingleton&.&Instance; Result := ordInst.mmax(v1, ordInst.mmax(v2, v3)); end; begin writeln(Max3&>(1, 2, 3)) end.