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