Primitive.cs 4.6 KB
Newer Older
BlackAngle233's avatar
BlackAngle233 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//=============================================================================================================================
//
// EasyAR Sense 4.2.0.8700-7bcbc8b1c
// Copyright (c) 2015-2021 VisionStar Information Technology (Shanghai) Co., Ltd. All Rights Reserved.
// EasyAR is the registered trademark or trademark of VisionStar Information Technology (Shanghai) Co., Ltd in China
// and other countries for the augmented reality technology developed by VisionStar Information Technology (Shanghai) Co., Ltd.
//
//=============================================================================================================================

using System;
using System.Collections.Generic;

namespace easyar
{
    public class AliasAttribute : Attribute { }
    public class RecordAttribute : Attribute { }
    public class TaggedUnionAttribute : Attribute { }
    public class TagAttribute : Attribute { }
    public class TupleAttribute : Attribute { }

    [Record]
    public struct Unit { }

    public enum OptionalTag
    {
        None = 0,
        Some = 1
    }
    [TaggedUnion]
    public struct Optional<T>
    {
        [Tag] public OptionalTag _Tag;

        public Unit None;
        public T Some;

        public static Optional<T> CreateNone() { return new Optional<T> { _Tag = OptionalTag.None, None = new Unit() }; }
        public static Optional<T> CreateSome(T Value) { return new Optional<T> { _Tag = OptionalTag.Some, Some = Value }; }

        public Boolean OnNone { get { return _Tag == OptionalTag.None; } }
        public Boolean OnSome { get { return _Tag == OptionalTag.Some; } }

        public static Optional<T> Empty { get { return CreateNone(); } }
        public static implicit operator Optional<T>(T v)
        {
            if (v == null)
            {
                return CreateNone();
            }
            else
            {
                return CreateSome(v);
            }
        }
        public static explicit operator T(Optional<T> v)
        {
            if (v.OnNone)
            {
                throw new InvalidOperationException();
            }
            return v.Some;
        }
        public static Boolean operator ==(Optional<T> Left, Optional<T> Right)
        {
            return Equals(Left, Right);
        }
        public static Boolean operator !=(Optional<T> Left, Optional<T> Right)
        {
            return !Equals(Left, Right);
        }
        public static Boolean operator ==(Optional<T>? Left, Optional<T>? Right)
        {
            return Equals(Left, Right);
        }
        public static Boolean operator !=(Optional<T>? Left, Optional<T>? Right)
        {
            return !Equals(Left, Right);
        }
        public override Boolean Equals(Object obj)
        {
            if (obj == null) { return Equals(this, null); }
            if (obj.GetType() != typeof(Optional<T>)) { return false; }
            var o = (Optional<T>)(obj);
            return Equals(this, o);
        }
        public override Int32 GetHashCode()
        {
            if (OnNone) { return 0; }
            return Some.GetHashCode();
        }

        private static Boolean Equals(Optional<T> Left, Optional<T> Right)
        {
            if (Left.OnNone && Right.OnNone)
            {
                return true;
            }
            if (Left.OnNone || Right.OnNone)
            {
                return false;
            }
            return Left.Some.Equals(Right.Some);
        }
        private static Boolean Equals(Optional<T>? Left, Optional<T>? Right)
        {
            if ((!Left.HasValue || Left.Value.OnNone) && (!Right.HasValue || Right.Value.OnNone))
            {
                return true;
            }
            if (!Left.HasValue || Left.Value.OnNone || !Right.HasValue || Right.Value.OnNone)
            {
                return false;
            }
            return Equals(Left.Value, Right.Value);
        }

        public T Value
        {
            get
            {
                if (OnSome)
                {
                    return Some;
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }
        public T ValueOrDefault(T Default)
        {
            if (OnSome)
            {
                return Some;
            }
            else
            {
                return Default;
            }
        }

        public override String ToString()
        {
            if (OnSome)
            {
                return Some.ToString();
            }
            else
            {
                return "-";
            }
        }
    }
}