1 // =================================
 2 // Copyright (c) 2022 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 using System.IO;
 7 using System.Concepts;
 8 
 9 namespace System
10 {
11     public class Pair<T, U> where T is Semiregular and U is Semiregular
12     {
13         public nothrow Pair() : first(), second() {}
14         public Pair(const T& first_, const U& second_) : first(first_), second(second_) {}
15         public T first;
16         public U second;
17     }
18 
19     public inline nothrow bool operator<<T, U>(const Pair<T, U>& left, const Pair<T, U>& right) where T is TotallyOrdered and U is TotallyOrdered
20     {
21         if (left.first < right.first) return true;
22         else if (left.first > right.first) return false;
23         else return left.second < right.second;
24     }
25 
26     public inline nothrow bool operator==<T, U>(const Pair<T, U>& left, const Pair<T, U>& right) where T is Regular and U is Regular
27     {
28         return left.first == right.first && left.second == right.second;
29     }
30 
31     public Pair<T, U> MakePair<T, U>(const T& first, const U& second) where T is Semiregular and U is Semiregular
32     {
33         return Pair<T, U>(first, second);
34     }
35 
36     public class SelectFirst<T, U> : UnaryFun<Pair<T, U>, T> where T is Semiregular and U is Semiregular
37     {
38         public inline nothrow const T& operator()(const Pair<T, U>& p) const
39         {
40             return p.first;
41         }
42     }
43 
44     public class SelectSecond<T, U> : UnaryFun<Pair<T, U>, U> where T is Semiregular and U is Semiregular
45     {
46         public inline nothrow const U& operator()(const Pair<T, U>& p) const
47         {
48             return p.second;
49         }
50     }
51 
52     [system_default="true"]
53     public TextWriter& operator<<<T, U>(TextWriter& writer, const Pair<T, U>& pair)
54     {
55         return writer << "(" << pair.first << ", " << pair.second << ")";
56     }
57 }