1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System.Concepts;
  7 
  8 namespace System
  9 {
 10     public class UnaryFun<ArgumentResult> where Argument is Semiregular
 11     {
 12         public typedef Argument ArgumentType;
 13         public typedef Result ResultType;
 14     }
 15 
 16     public class BinaryFun<Argument1Argument2Result> where Argument1 is Semiregular and Argument2 is Semiregular
 17     {
 18         public typedef Argument1 FirstArgumentType;
 19         public typedef Argument2 SecondArgumentType;
 20         public typedef Result ResultType;
 21     }
 22 
 23     public class Plus<T> : BinaryFun<TTT> where T is AdditiveSemigroup
 24     {
 25         public inline nothrow T operator()(const T& aconst T& b) const
 26         {
 27             return a + b;
 28         }
 29     }
 30 
 31     public inline nothrow T IdentityElement<T>(Plus<T>) where T is AdditiveMonoid
 32     {
 33         return T(0);
 34     }
 35 
 36     public class Negate<T> : UnaryFun<TT> where T is AdditiveGroup
 37     {
 38         public inline nothrow T operator()(const T& a) const
 39         {
 40             return -a;
 41         }
 42     }
 43 
 44     public class Minus<T> : BinaryFun<TTT> where T is AdditiveGroup
 45     {
 46         public inline nothrow T operator()(const T& aconst T& b) const
 47         {
 48             return a - b;
 49         }
 50     }
 51 
 52     public class Multiplies<T> : BinaryFun<TTT> where T is MultiplicativeSemigroup
 53     {
 54         public inline nothrow T operator()(const T& aconst T& b) const
 55         {
 56             return a * b;
 57         }
 58     }
 59 
 60     public inline nothrow T IdentityElement<T>(Multiplies<T>) where T is MultiplicativeMonoid
 61     {
 62         return T(1);
 63     }
 64 
 65     public class Divides<T> : BinaryFun<TTT> where T is MultiplicativeGroup
 66     {
 67         public inline nothrow T operator()(const T& aconst T& b) const
 68         {
 69             return a / b;
 70         }
 71     }
 72 
 73     public class Remainder<T> : BinaryFun<TTT> where T is EuclideanSemiring
 74     {
 75         public inline nothrow T operator()(const T& aconst T& b) const
 76         {
 77             return a % b;
 78         }
 79     }
 80 
 81     public class UnaryPred<Argument> : UnaryFun<Argumentbool> where Argument is Semiregular
 82     {
 83     }
 84 
 85     public class BinaryPred<Argument1Argument2> : BinaryFun<Argument1Argument2bool> where Argument1 is Semiregular and Argument2 is Semiregular
 86     {
 87     }
 88 
 89     public class Rel<Argument> : BinaryPred<ArgumentArgument> where Argument is Semiregular
 90     {
 91         public typedef Argument Domain;
 92     }
 93 
 94     public class Identity<T> : UnaryFun<TT> where T is Semiregular
 95     {
 96         public inline nothrow const T& operator()(const T& x) const
 97         {
 98             return x;
 99         }
100     }
101 
102     public class EqualTo<T> : Rel<T> where T is Regular
103     {
104         public inline nothrow bool operator()(const T& leftconst T& right) const
105         {
106             return left == right;
107         }
108     }
109 
110     public class EqualTo<TU> : BinaryPred<TU> where EqualityComparable<TU>
111     {
112         public inline nothrow bool operator()(const T& leftconst U& right) const
113         {
114             return left == right;
115         }
116     }
117 
118     public class NotEqualTo<T> : Rel<T> where T is Regular
119     {
120         public inline nothrow bool operator()(const T& leftconst T& right) const
121         {
122             return left != right;
123         }
124     }
125 
126     public class NotEqualTo<TU> : BinaryPred<TU> where EqualityComparable<TU>
127     {
128         public inline nothrow bool operator()(const T& leftconst U& right) const
129         {
130             return left != right;
131         }
132     }
133 
134     public class Less<T> : Rel<T> where T is LessThanComparable
135     {
136         public inline nothrow bool operator()(const T& leftconst T& right) const
137         {
138             return left < right;
139         }
140     }
141 
142     public class Less<TU> : BinaryPred<TU> where LessThanComparable<TU>
143     {
144         public inline nothrow bool operator()(const T& leftconst U& right) const
145         {
146             return left < right;
147         }
148     }
149 
150     public class Greater<T> : Rel<T> where T is LessThanComparable
151     {
152         public inline nothrow bool operator()(const T& leftconst T& right) const
153         {
154             return left > right;
155         }
156     }
157 
158     public class Greater<TU> : BinaryPred<TU> where LessThanComparable<TU>
159     {
160         public inline nothrow bool operator()(const T& leftconst U& right) const
161         {
162             return left > right;
163         }
164     }
165 
166     public class LessOrEqualTo<T> : Rel<T> where T is LessThanComparable
167     {
168         public inline nothrow bool operator()(const T& leftconst T& right) const
169         {
170             return left <= right;
171         }
172     }
173 
174     public class LessOrEqualTo<TU> : BinaryPred<TU> where LessThanComparable<TU>
175     {
176         public inline nothrow bool operator()(const T& leftconst U& right) const
177         {
178             return left <= right;
179         }
180     }
181 
182     public class GreaterOrEqualTo<T> : Rel<T> where T is LessThanComparable
183     {
184         public inline nothrow bool operator()(const T& leftconst T& right) const
185         {
186             return left >= right;
187         }
188     }
189 
190     public class GreaterOrEqualTo<TU> : BinaryPred<TU> where LessThanComparable<TU>
191     {
192         public inline nothrow bool operator()(const T& leftconst U& right) const
193         {
194             return left >= right;
195         }
196     }
197 
198     public class LogicalAnd<T = bool> : BinaryPred<boolbool>
199     {
200         public inline nothrow bool operator()(bool leftbool right) const
201         {
202             return left && right;
203         }
204     }
205 
206     public class LogicalOr<T = bool> : BinaryPred<boolbool>
207     {
208         public inline nothrow bool operator()(bool leftbool right) const
209         {
210             return left || right;
211         }
212     }
213 
214     public class LogicalNot<T = bool> : UnaryPred<bool>
215     {
216         public inline nothrow bool operator()(bool operand) const
217         {
218             return !operand;
219         }
220     }
221 
222     public class BitAnd<T> : BinaryFun<TTT> where T is Semiregular
223     {
224         public inline nothrow T operator()(const T& leftconst T& right) const
225         {
226             return left & right;
227         }
228     }
229 
230     public class BitOr<T> : BinaryFun<TTT> where T is Semiregular
231     {
232         public inline nothrow T operator()(const T& leftconst T& right) const
233         {
234             return left | right;
235         }
236     }
237 
238     public class BitXor<T> : BinaryFun<TTT> where T is Semiregular
239     {
240         public inline nothrow T operator()(const T& leftconst T& right) const
241         {
242             return left ^ right;
243         }
244     }
245 
246     public class BitNot<T> : UnaryFun<TT> where T is Semiregular
247     {
248         public inline nothrow T operator()(const T& operand) const
249         {
250             return ~operand;
251         }
252     }
253 
254     public class ShiftLeft<T> : BinaryFun<TTT> where T is Semiregular
255     {
256         public inline nothrow T operator()(const T& leftconst T& right) const
257         {
258             return left << right;
259         }
260     }
261 
262     public class ShiftRight<T> : BinaryFun<TTT> where T is Semiregular
263     {
264         public inline nothrow T operator()(const T& leftconst T& right) const
265         {
266             return left >> right;
267         }
268     }
269 }