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