-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
sorted_triplet.h
95 lines (71 loc) · 3.2 KB
/
sorted_triplet.h
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
#pragma once
#include <algorithm>
#include <array>
#include <tuple>
#include <utility>
#include "drake/common/drake_copyable.h"
#include "drake/common/is_less_than_comparable.h"
namespace drake {
namespace geometry {
namespace internal {
// TODO(DamrongGuoy): If we add hash_append, change the documentation below
// to say it can be used with std::unordered_map and std::unordered_set.
// This class is similar to the drake::SortedPair class. However, this class
// uses a triplet of homogeneous types. Both SortedPair and SortedTriplet
// sort the values such that one value is less than or equal to the next one.
// The SortedTriplet class can be used to generate keys for std::map (or
// std::set) from triplets of objects. However, it cannot be used to
// generate keys for std::unordered_map (or std::unordered_set).
//
// @tparam T A template type that provides `operator<` and supports default
// construction.
template<class T>
struct SortedTriplet {
DRAKE_DEFAULT_COPY_AND_MOVE_AND_ASSIGN(SortedTriplet)
static_assert(is_less_than_comparable<T>::value,
"SortedTriplet can only be used with types that can be "
"compared using the less-than operator (operator<).");
// The default constructor creates the three objects using their
// respective default constructors.
SortedTriplet() = default;
// TODO(DamrongGuoy): Add rvalue reference constructor, permits constructing
// with std::unique_ptr types, for example.
// Constructs a %SortedTriplet from three objects.
SortedTriplet(const T& a, const T& b, const T& c) : objects_{a, b, c} {
std::stable_sort(objects_.begin(), objects_.end());
}
// TODO(DamrongGuoy): Add type-converting copy constructor.
// TODO(DamrongGuoy): Add set(a,b,c) to reset the stored objects.
// Gets the first (according to `operator<`) of the objects.
const T& first() const { return objects_[0]; }
// Gets the second (according to `operator<`) of the objects.
const T& second() const { return objects_[1]; }
// Gets the third (according to `operator<`) of the objects.
const T& third() const { return objects_[2]; }
// TODO(DamrongGuoy): Add Swap(t) to swap `this` and `t`.
// TODO(DamrongGuoy): Add hash_append(HashAlgorithm&, SortedTriplet&) to
// implement the hash_append concept.
private:
// The three objects in the order of T::operator<.
std::array<T, 3> objects_{};
};
// Two triplets of the same type are equal iff their members are equal after
// sorting.
template<class T>
inline bool operator==(const SortedTriplet<T>& x, const SortedTriplet<T>& y) {
return !(x < y) && !(y < x);
}
// Compares two triplets using lexicographic ordering.
template<class T>
inline bool operator<(const SortedTriplet<T>& x, const SortedTriplet<T>& y) {
return std::tie(x.first(), x.second(), x.third()) <
std::tie(y.first(), y.second(), y.third());
}
// TODO(DamrongGuoy): Provide operators !=, >, <=, >=.
// TODO(DamrongGuoy): Provide MakeSortedTriplet() a convenience wrapper for
// creating a sorted triplet from three objects.
} // namespace internal
} // namespace geometry
} // namespace drake
// TODO(DamrongGuoy): Implement std::swap().
// TODO(DamrongGuoy): Implement std::hash<SortedTriplet<T>>.