1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using System.Collections.Generic;
10 
11 namespace Antmicro.Renode.Utilities.Collections
12 {
13     /// <summary>
14     /// Defines a basic interval concept. A stucture that has a beginning and and end and can answer the questions, whether it contains a scalar, or encloses another interval.
15     /// </summary>
16     public interface IInterval<TScalar> where TScalar : struct, IComparable<TScalar>
17     {
Contains(TScalar x)18         bool Contains(TScalar x);
19 
Contains(IInterval<TScalar> interval)20         bool Contains(IInterval<TScalar> interval);
21 
22         TScalar Start { get; }
23 
24         TScalar End { get; }
25     }
26 
27     /// <summary>
28     /// Interval comparer. Implements normal comparer and equality comparer which is needed by Distinct Linq method.
29     /// Interval is larger than the other when it start later. If both start at the same address, the one that ends earlier is larger.
30     /// It makes the symbols that are enclosed within other to appear later than them.
31     /// </summary>
32     public class IntervalComparer<TScalar> : Comparer<IInterval<TScalar>>, IEqualityComparer<IInterval<TScalar>> where TScalar : struct, IComparable<TScalar>
33     {
Compare(IInterval<TScalar> lhs, IInterval<TScalar> rhs)34         public override int Compare(IInterval<TScalar> lhs, IInterval<TScalar> rhs)
35         {
36             if(lhs.Start.CompareTo(rhs.Start) != 0)
37             {
38                 return lhs.Start.CompareTo(rhs.Start);
39             }
40             return rhs.End.CompareTo(lhs.End);
41         }
42 
Equals(IInterval<TScalar> x, IInterval<TScalar> y)43         public bool Equals(IInterval<TScalar> x, IInterval<TScalar> y)
44         {
45             return Compare(x, y) == 0;
46         }
47 
GetHashCode(IInterval<TScalar> obj)48         public int GetHashCode(IInterval<TScalar> obj)
49         {
50             unchecked
51             {
52                 const int funnyPrime1 = 9901;
53                 const int funnyPrime2 = 99990001;
54                 int hash1 = obj.Start.GetHashCode();
55                 int hash2 = obj.End.GetHashCode();
56                 int hash = (hash1 * funnyPrime1) ^ (hash2 * funnyPrime2);
57                 return hash;
58             }
59         }
60     }
61 
62     /// <summary>
63     /// Basic reference implementation of an interval.
64     /// </summary>
65     public class Interval<TScalar> : IInterval<TScalar> where TScalar : struct, IComparable<TScalar>
66     {
Interval(TScalar start, TScalar end)67         public Interval(TScalar start, TScalar end)
68         {
69             Start = start;
70             End = end;
71         }
72 
Contains(TScalar x)73         public bool Contains(TScalar x)
74         {
75             var startCompare = Start.CompareTo(x);
76             return (startCompare == 0 || ((startCompare < 0) && (End.CompareTo(x) > 0)));
77         }
78 
Contains(IInterval<TScalar> other)79         public bool Contains(IInterval<TScalar> other)
80         {
81             return (Start.CompareTo(other.Start) <= 0) && (End.CompareTo(other.End) > 0);
82         }
83 
84         public TScalar Start { get; set; }
85 
86         public TScalar End { get; set; }
87     }
88 }
89 
90