MeshLib C++ Docs
Loading...
Searching...
No Matches
MRMesh/MRId.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRMeshFwd.h"
4#include "MRMacros.h"
5#include <cassert>
6#include <cstddef>
7#include <type_traits>
8#include <utility>
9
10namespace MR
11{
12
13// stores index of some element, it is made as template class to avoid mixing faces, edges and vertices
14template <typename T>
15class Id
16{
17public:
18 using ValueType = int; //the type used for internal representation of Id
19
20 constexpr Id() noexcept : id_( -1 ) { }
21 explicit Id( NoInit ) noexcept { }
22
23 // Allow constructing from `int` and other integral types.
24 // This constructor is written like this instead of a plain `Id(int)`, because we also wish to disable construction
25 // from other unrelated `Id<U>` specializations, which themselves have implicit conversions to `int`.
26 // We could also achieve that using `template <typename U> Id(Id<U>) = delete;`, but it turns out that that causes issues
27 // for the `EdgeId::operator UndirectedEdgeId` below. There, while `UndirectedEdgeId x = EdgeId{};` compiles with this approach,
28 // but `UndirectedEdgeId x(EdgeId{});` doesn't. So to allow both forms, this constructor must be written this way, as a template.
29 // The `= int` is there only to make the bindings emit this constructor, I don't think it affects anything else.
30 template <typename U = int
31 // The condition is there for the binding generator. Firstly, removing the second template argument produces better function names in C,
32 // and secondly `--buggy-substitute-default-template-args` seems to duplicate this constructor when `enable_if_t` is present.
33 #if MR_HAS_REQUIRES
34 > requires std::is_integral_v<U>
35 #else
36 , std::enable_if_t<std::is_integral_v<U>, std::nullptr_t> = nullptr>
37 #endif
38 explicit constexpr Id( U i ) noexcept : id_( ValueType( i ) ) { }
39
40 constexpr operator ValueType() const { return id_; }
41 constexpr bool valid() const { return id_ >= 0; }
42 explicit constexpr operator bool() const { return id_ >= 0; }
43 constexpr ValueType & get() noexcept { return id_; }
44
45 constexpr bool operator == (Id b) const { return id_ == b.id_; }
46 constexpr bool operator != (Id b) const { return id_ != b.id_; }
47 constexpr bool operator < (Id b) const { return id_ < b.id_; }
48
49 template <typename U>
50 bool operator == (Id<U> b) const = delete;
51 template <typename U>
52 bool operator != (Id<U> b) const = delete;
53 template <typename U>
54 bool operator < (Id<U> b) const = delete;
55
56 constexpr Id & operator --() { --id_; return * this; }
57 constexpr Id & operator ++() { ++id_; return * this; }
58
59 constexpr Id operator --( int ) { auto res = *this; --id_; return res; }
60 constexpr Id operator ++( int ) { auto res = *this; ++id_; return res; }
61
62 constexpr Id & operator -=( ValueType a ) { id_ -= a; return * this; }
63 constexpr Id & operator +=( ValueType a ) { id_ += a; return * this; }
64
65// Allocating IDs on the heap in C is insufferable, so instead we bind them as single-member structs (via `--expose-as-struct`).
66// But since our parser only tracks public members, we have to make it public for C.
67#if !MR_PARSING_FOR_C_BINDINGS && !MR_COMPILING_C_BINDINGS
68private:
69#endif
70
71 ValueType id_;
72};
73
74// Variant of Id<T> with omitted initialization by default. Useful for containers.
75template <typename T>
76class NoInitId : public Id<T>
77{
78public:
79 NoInitId() : Id<T>( noInit ) {}
80 NoInitId( Id<T> id ) : Id<T>( id ) {}
81};
82
83template <>
84class Id<EdgeTag>
85{
86public:
87 using ValueType = int; //the type used for internal representation of Id
88
89 constexpr Id() noexcept : id_( -1 ) { }
90 explicit Id( NoInit ) noexcept { }
91 constexpr Id( UndirectedEdgeId u ) noexcept : id_( (ValueType)u << 1 ) { assert( u.valid() ); }
92 explicit constexpr Id( ValueType i ) noexcept : id_( i ) { }
93 explicit constexpr Id( unsigned int i ) noexcept : id_( i ) { }
94 explicit constexpr Id( size_t i ) noexcept : id_( ValueType( i ) ) { }
95 constexpr operator ValueType() const { return id_; }
96 constexpr bool valid() const { return id_ >= 0; }
97 explicit constexpr operator bool() const { return id_ >= 0; }
98 constexpr ValueType & get() noexcept { return id_; }
99
100 // returns identifier of the edge with same ends but opposite orientation
101 constexpr Id sym() const { assert( valid() ); return Id(id_ ^ 1); }
102 // among each pair of sym-edges: one is always even and the other is odd
103 constexpr bool even() const { assert( valid() ); return (id_ & 1) == 0; }
104 constexpr bool odd() const { assert( valid() ); return (id_ & 1) == 1; }
105 // returns unique identifier of the edge ignoring its direction
106 constexpr UndirectedEdgeId undirected() const { assert( valid() ); return UndirectedEdgeId( id_ >> 1 ); }
107 constexpr operator UndirectedEdgeId() const { return undirected(); }
108
109 constexpr bool operator == (Id b) const { return id_ == b.id_; }
110 constexpr bool operator != (Id b) const { return id_ != b.id_; }
111 constexpr bool operator < (Id b) const { return id_ < b.id_; }
112
113 template <typename U>
114 bool operator == (Id<U> b) const = delete;
115 template <typename U>
116 bool operator != (Id<U> b) const = delete;
117 template <typename U>
118 bool operator < (Id<U> b) const = delete;
119
120 constexpr Id & operator --() { --id_; return * this; }
121 constexpr Id & operator ++() { ++id_; return * this; }
122
123 constexpr Id operator --( int ) { auto res = *this; --id_; return res; }
124 constexpr Id operator ++( int ) { auto res = *this; ++id_; return res; }
125
126 constexpr Id & operator -=( ValueType a ) { id_ -= a; return * this; }
127 constexpr Id & operator +=( ValueType a ) { id_ += a; return * this; }
128
129// See the primary template for explanation.
130#if !MR_PARSING_FOR_C_BINDINGS && !MR_COMPILING_C_BINDINGS
131private:
132#endif
133
134 ValueType id_;
135};
136
137template <>
139{
140public:
141 using ValueType = size_t; //the type used for internal representation of Id
142
143 constexpr Id() noexcept : id_( ~ValueType( 0 ) ) { }
144 explicit Id( NoInit ) noexcept { }
145 explicit constexpr Id( ValueType i ) noexcept : id_( i ) { }
146 explicit constexpr Id( int ) noexcept = delete;
147 constexpr operator ValueType() const { return id_; }
148 constexpr bool valid() const { return id_ != ~ValueType( 0 ); }
149 explicit constexpr operator bool() const { return id_ != ~ValueType( 0 ); }
150 constexpr ValueType& get() noexcept { return id_; }
151
152 constexpr bool operator == (Id b) const { return id_ == b.id_; }
153 constexpr bool operator != (Id b) const { return id_ != b.id_; }
154 constexpr bool operator < (Id b) const { return id_ < b.id_; }
155
156 template <typename U>
157 bool operator == (Id<U> b) const = delete;
158 template <typename U>
159 bool operator != (Id<U> b) const = delete;
160 template <typename U>
161 bool operator < (Id<U> b) const = delete;
162
163 constexpr Id & operator --() { --id_; return * this; }
164 constexpr Id & operator ++() { ++id_; return * this; }
165
166 constexpr Id operator --( int ) { auto res = *this; --id_; return res; }
167 constexpr Id operator ++( int ) { auto res = *this; ++id_; return res; }
168
169 constexpr Id & operator -=( ValueType a ) { id_ -= a; return * this; }
170 constexpr Id & operator +=( ValueType a ) { id_ += a; return * this; }
171
172// See the primary template for explanation.
173#if !MR_PARSING_FOR_C_BINDINGS && !MR_COMPILING_C_BINDINGS
174private:
175#endif
176
177 ValueType id_;
178};
179
180template <typename T>
181inline constexpr Id<T> operator + ( Id<T> id, int a ) { return Id<T>{ id.get() + a }; }
182template <typename T>
183inline constexpr Id<T> operator + ( Id<T> id, unsigned int a ) { return Id<T>{ id.get() + a }; }
184template <typename T>
185inline constexpr Id<T> operator + ( Id<T> id, size_t a ) { return Id<T>{ id.get() + a }; }
186
187template <typename T>
188inline constexpr Id<T> operator - ( Id<T> id, int a ) { return Id<T>{ id.get() - a }; }
189template <typename T>
190inline constexpr Id<T> operator - ( Id<T> id, unsigned int a ) { return Id<T>{ id.get() - a }; }
191template <typename T>
192inline constexpr Id<T> operator - ( Id<T> id, size_t a ) { return Id<T>{ id.get() - a }; }
193
194inline constexpr FaceId operator ""_f( unsigned long long i ) noexcept { return FaceId{ (int)i }; }
195inline constexpr VertId operator ""_v( unsigned long long i ) noexcept { return VertId{ (int)i }; }
196inline constexpr EdgeId operator ""_e( unsigned long long i ) noexcept { return EdgeId{ (int)i }; }
197inline constexpr UndirectedEdgeId operator ""_ue( unsigned long long i ) noexcept { return UndirectedEdgeId{ (int)i }; }
198inline constexpr VoxelId operator ""_vox( unsigned long long i ) noexcept { return VoxelId{ size_t( i ) }; }
199
200} //namespace MR
201
202template <typename T>
203struct std::hash<MR::Id<T>>
204{
205 size_t operator() ( MR::Id<T> const& p ) const noexcept
206 {
207 return (int)p;
208 }
209};
constexpr bool odd() const
Definition MRMesh/MRId.h:104
constexpr bool valid() const
Definition MRMesh/MRId.h:96
int ValueType
Definition MRMesh/MRId.h:87
constexpr Id sym() const
Definition MRMesh/MRId.h:101
Id(NoInit) noexcept
Definition MRMesh/MRId.h:90
constexpr Id(UndirectedEdgeId u) noexcept
Definition MRMesh/MRId.h:91
constexpr Id(ValueType i) noexcept
Definition MRMesh/MRId.h:92
constexpr Id(size_t i) noexcept
Definition MRMesh/MRId.h:94
constexpr Id() noexcept
Definition MRMesh/MRId.h:89
constexpr Id(unsigned int i) noexcept
Definition MRMesh/MRId.h:93
constexpr ValueType & get() noexcept
Definition MRMesh/MRId.h:98
constexpr bool even() const
Definition MRMesh/MRId.h:103
constexpr UndirectedEdgeId undirected() const
Definition MRMesh/MRId.h:106
constexpr bool valid() const
Definition MRMesh/MRId.h:148
size_t ValueType
Definition MRMesh/MRId.h:141
constexpr ValueType & get() noexcept
Definition MRMesh/MRId.h:150
constexpr Id() noexcept
Definition MRMesh/MRId.h:143
Id(NoInit) noexcept
Definition MRMesh/MRId.h:144
constexpr Id(int) noexcept=delete
constexpr Id(ValueType i) noexcept
Definition MRMesh/MRId.h:145
Definition MRMesh/MRId.h:16
constexpr bool operator!=(Id b) const
Definition MRMesh/MRId.h:46
constexpr Id & operator+=(ValueType a)
Definition MRMesh/MRId.h:63
constexpr Id & operator++()
Definition MRMesh/MRId.h:57
Id(NoInit) noexcept
Definition MRMesh/MRId.h:21
constexpr bool operator==(Id b) const
Definition MRMesh/MRId.h:45
constexpr bool valid() const
Definition MRMesh/MRId.h:41
constexpr Id & operator-=(ValueType a)
Definition MRMesh/MRId.h:62
constexpr Id & operator--()
Definition MRMesh/MRId.h:56
constexpr Id() noexcept
Definition MRMesh/MRId.h:20
constexpr bool operator<(Id b) const
Definition MRMesh/MRId.h:47
constexpr ValueType & get() noexcept
Definition MRMesh/MRId.h:43
int ValueType
Definition MRMesh/MRId.h:18
constexpr Id(U i) noexcept
Definition MRMesh/MRId.h:38
Definition MRMesh/MRId.h:77
NoInitId()
Definition MRMesh/MRId.h:79
NoInitId(Id< T > id)
Definition MRMesh/MRId.h:80
BitSet operator-(const BitSet &a, const BitSet &b)
Definition MRMesh/MRBitSet.h:438
Definition MRCameraOrientationPlugin.h:8
class MRMESH_CLASS VoxelTag
Definition MRMesh/MRMeshFwd.h:99
constexpr NoInit noInit
Definition MRMesh/MRMeshFwd.h:91
class MRMESH_CLASS EdgeTag
Definition MRMesh/MRMeshFwd.h:94
Color operator+(const Color &a, const Color &b)
Definition MRMesh/MRColor.h:106
Definition MRMesh/MRMeshFwd.h:90