summaryrefslogtreecommitdiff
path: root/runtimes/neurun/core/include/util/Index.h
blob: d1fdc237c98a0443cfe5024ae18f92272dcab763 (plain)
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
156
157
158
/*
 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __NEURUN_UTIL_INDEX_H__
#define __NEURUN_UTIL_INDEX_H__

#include <functional>
#include <limits>
#include <stdint.h>

namespace neurun
{
namespace util
{

/**
 * @brief A wrapper class for unsigned integral Index
 *        NOTE : Max value of the underlying type is used as the invalid value
 *
 * @tparam T Underlying type. Must be unsigned integral type otherwise its behavior is undefined.
 * @tparam DummyTag Dummy type to distinguish types with a same underlying type. Using an opaque
 * type is recommended.
 */
template <typename T, typename DummyTag> class Index
{
private:
  static const T UNDEFINED = std::numeric_limits<T>::max();

public:
  /**
   * @brief Construct a new Index object
   */
  explicit Index(void) : _index{UNDEFINED} {}
  /**
   * @brief Construct a new Index object with a value in the underlying type
   *
   * @param o Value in the underlying type
   */
  explicit Index(T o) : _index{o} {}
  /**
   * @brief Copy Constructor
   *
   * @param o Object to be copied
   */
  Index(const Index &o) : _index{o._index} {}

  /**
   * @brief Assign a value in the underlying time
   *
   * @param o Value in the underlying type
   * @return Index& Reference of this pointer
   */
  Index &operator=(T o)
  {
    _index = o;
    return *this;
  }

  /**
   * @brief Copy assignment operator
   *
   * @param o Object to be copied
   * @return Index& Reference of this pointer
   */
  Index &operator=(const T &o)
  {
    _index = o._index;
    return *this;
  }

  /**
   * @brief Equality operator
   *
   * @param o The other value in the underlying type to compare
   * @return true if underlying value is the same, false otherwise
   */
  bool operator==(T o) const { return _index == o; }
  /**
   * @brief Equality operator
   *
   * @param o The other object to compare
   * @return true if underlying value is the same, false otherwise
   */
  bool operator==(const Index &o) const { return _index == o._index; }
  /**
   * @brief Inquality operator
   *
   * @param o The other value in the underlying type to compare
   * @return true if underlying value is the same, false otherwise
   */
  bool operator!=(T o) const { return !(*this == o); }
  /**
   * @brief Inquality operator
   *
   * @param o The other object to compare
   * @return true if underlying value is the same, false otherwise
   */
  bool operator!=(const Index &o) const { return !(*this == o); }

  /**
   * @brief Post increment operator
   *
   * @return Index Index before increment
   */
  Index operator++(int)
  {
    Index temp = *this;
    _index++;
    return temp;
  }

  /**
   * @brief Check whether the value is valid or not
   *
   * @return true if valid, false otherwise
   */
  bool valid() const { return _index != UNDEFINED; }
  /**
   * @brief Return underlying value
   *
   * @return T Underlying value
   */
  T value() const { return _index; }

private:
  T _index;
};

} // namespace util
} // namespace neurun

namespace std
{

template <typename T, typename Tag> struct hash<::neurun::util::Index<T, Tag>>
{
  size_t operator()(const ::neurun::util::Index<T, Tag> &index) const noexcept
  {
    return hash<T>()(index.value());
  }
};

} // namespace std

#endif // __NEURUN_UTIL_INDEX_H__