Skip to content

Commit b50bf9c

Browse files
authored
Merge pull request #3141 from pleroy/SegmentIterator
DiscreteTrajectorySegmentIterator
2 parents d047406 + 003a571 commit b50bf9c

10 files changed

+292
-27
lines changed

physics/discrete_trajectory_iterator.hpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,13 @@ class DiscreteTrajectoryIterator {
3333
private:
3434
using Timeline = internal_discrete_trajectory_types::Timeline<Frame>;
3535

36-
DiscreteTrajectorySegmentIterator segment_;
36+
DiscreteTrajectorySegmentIterator<Frame> segment_;
3737
Timeline::const_iterator point_;
3838
};
3939

4040
} // namespace internal_discrete_trajectory_iterator
4141

42-
template<typename Frame>
43-
using DiscreteTrajectoryIterator =
44-
internal_discrete_trajectory_iterator::DiscreteTrajectoryIterator;
42+
using internal_discrete_trajectory_iterator::DiscreteTrajectoryIterator;
4543

4644
} // namespace physics
4745
} // namespace principia

physics/discrete_trajectory_segment.hpp

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <cstdint>
4+
35
#include "absl/container/btree_map.h"
46
#include "absl/container/btree_set.h"
57
#include "geometry/named_quantities.hpp"
@@ -19,6 +21,7 @@ template<typename Frame>
1921
class DiscreteTrajectorySegment {
2022
public:
2123
DiscreteTrajectorySegment() = default;
24+
virtual ~DiscreteTrajectorySegment() = default;
2225

2326
// Moveable.
2427
DiscreteTrajectorySegment(DiscreteTrajectorySegment&&) = default;
@@ -38,29 +41,42 @@ class DiscreteTrajectorySegment {
3841
DiscreteTrajectoryIterator<Frame> lower_bound(Instant const& t) const;
3942
DiscreteTrajectoryIterator<Frame> upper_bound(Instant const& t) const;
4043

41-
private:
44+
bool empty() const;
45+
virtual std::int64_t size() const;
46+
47+
protected:
48+
// For mocking.
4249
using Timeline = internal_discrete_trajectory_types::Timeline<Frame>;
4350

51+
private:
4452
void Append(Instant const& t,
4553
DegreesOfFreedom<Frame> const& degrees_of_freedom);
4654

4755
void ForgetAfter(Instant const& t);
48-
void ForgetAfter(Timeline::const_iterator begin);
56+
void ForgetAfter(typename Timeline::const_iterator begin);
4957

5058
void ForgetBefore(Instant const& t);
51-
void ForgetBefore(Timeline::const_iterator end);
59+
void ForgetBefore(typename Timeline::const_iterator end);
5260

53-
DiscreteTrajectorySegmentIterator<Frame> that_;
61+
virtual typename Timeline::const_iterator timeline_begin() const;
62+
virtual typename Timeline::const_iterator timeline_end() const;
63+
64+
DiscreteTrajectorySegmentIterator<Frame> self_;
5465

5566
Timeline timeline_;
5667
absl::btree_set<Instant> dense_points_;
68+
69+
template<typename F>
70+
friend class internal_discrete_trajectory_iterator::
71+
DiscreteTrajectoryIterator;
72+
friend class physics::DiscreteTrajectoryIteratorTest;
5773
};
5874

5975
} // namespace internal_discrete_trajectory_segment
6076

61-
template<typename Frame>
62-
using DiscreteTrajectorySegment =
63-
internal_discrete_trajectory_segment::DiscreteTrajectorySegment;
77+
using internal_discrete_trajectory_segment::DiscreteTrajectorySegment;
6478

6579
} // namespace physics
6680
} // namespace principia
81+
82+
#include "physics/discrete_trajectory_segment_body.hpp"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include "glog/logging.h"
4+
#include "physics/discrete_trajectory_segment.hpp"
5+
6+
namespace principia {
7+
namespace physics {
8+
namespace internal_discrete_trajectory_segment {
9+
10+
template<typename Frame>
11+
typename DiscreteTrajectorySegment<Frame>::Timeline::const_iterator
12+
DiscreteTrajectorySegment<Frame>::timeline_begin() const {
13+
LOG(FATAL) << "NYI";
14+
}
15+
16+
template<typename Frame>
17+
typename DiscreteTrajectorySegment<Frame>::Timeline::const_iterator
18+
DiscreteTrajectorySegment<Frame>::timeline_end() const {
19+
LOG(FATAL) << "NYI";
20+
}
21+
22+
template<typename Frame>
23+
std::int64_t DiscreteTrajectorySegment<Frame>::size() const {
24+
LOG(FATAL) << "NYI";
25+
}
26+
27+
} // namespace internal_discrete_trajectory_segment
28+
} // namespace physics
29+
} // namespace principia
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
#pragma once
22

3-
#include <list>
4-
#include <memory>
5-
63
#include "absl/container/btree_map.h"
7-
#include "geometry/named_quantities.hpp"
8-
#include "physics/degrees_of_freedom.hpp"
4+
#include "base/macros.hpp"
5+
#include "base/not_null.hpp"
96
#include "physics/discrete_trajectory_types.hpp"
107

118
namespace principia {
129
namespace physics {
1310

14-
template<typename Frame>
15-
class DiscreteTrajectorySegment;
11+
FORWARD_DECLARE_FROM(discrete_trajectory_iterator,
12+
TEMPLATE(typename Frame) class,
13+
DiscreteTrajectoryIterator);
14+
FORWARD_DECLARE_FROM(discrete_trajectory_segment,
15+
TEMPLATE(typename Frame) class,
16+
DiscreteTrajectorySegment);
17+
18+
class DiscreteTrajectoryIteratorTest;
19+
class DiscreteTrajectorySegmentIteratorTest;
1620

1721
namespace internal_discrete_trajectory_segment_iterator {
1822

19-
using geometry::Instant;
20-
using physics::DegreesOfFreedom;
23+
using base::not_null;
2124

2225
template<typename Frame>
2326
class DiscreteTrajectorySegmentIterator {
@@ -32,18 +35,34 @@ class DiscreteTrajectorySegmentIterator {
3235
DiscreteTrajectorySegment<Frame> const& operator*() const;
3336
DiscreteTrajectorySegment<Frame> const* operator->() const;
3437

38+
bool operator==(DiscreteTrajectorySegmentIterator const& other) const;
39+
bool operator!=(DiscreteTrajectorySegmentIterator const& other) const;
40+
3541
private:
3642
using Segments = internal_discrete_trajectory_types::Segments<Frame>;
3743

38-
Segments::const_iterator segment_;
44+
DiscreteTrajectorySegmentIterator(not_null<Segments const*> segments,
45+
typename Segments::const_iterator iterator);
46+
47+
DiscreteTrajectorySegmentIterator begin() const;
48+
DiscreteTrajectorySegmentIterator end() const;
49+
50+
// Not not_null<> to be default-constructible.
51+
Segments const* segments_ = nullptr;
52+
typename Segments::const_iterator iterator_;
53+
54+
template<typename Frame>
55+
friend class DiscreteTrajectoryIterator;
56+
friend class DiscreteTrajectoryIteratorTest;
57+
friend class DiscreteTrajectorySegmentIteratorTest;
3958
};
4059

4160
} // namespace internal_discrete_trajectory_segment_iterator
4261

43-
template<typename Frame>
44-
using DiscreteTrajectorySegmentIterator =
45-
internal_discrete_trajectory_segment_iterator::
46-
DiscreteTrajectorySegmentIterator;
62+
using internal_discrete_trajectory_segment_iterator::
63+
DiscreteTrajectorySegmentIterator;
4764

4865
} // namespace physics
4966
} // namespace principia
67+
68+
#include "physics/discrete_trajectory_segment_iterator_body.hpp"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#include "physics/discrete_trajectory_segment_iterator.hpp"
2+
3+
namespace principia {
4+
namespace physics {
5+
namespace internal_discrete_trajectory_segment_iterator {
6+
7+
template<typename Frame>
8+
DiscreteTrajectorySegmentIterator<Frame>&
9+
DiscreteTrajectorySegmentIterator<Frame>::operator++() {
10+
++iterator_;
11+
return *this;
12+
}
13+
14+
template<typename Frame>
15+
DiscreteTrajectorySegmentIterator<Frame>&
16+
DiscreteTrajectorySegmentIterator<Frame>::operator--() {
17+
--iterator_;
18+
return *this;
19+
}
20+
21+
template<typename Frame>
22+
DiscreteTrajectorySegmentIterator<Frame>
23+
DiscreteTrajectorySegmentIterator<Frame>::operator++(int) { // NOLINT
24+
return DiscreteTrajectorySegmentIterator(segments_, iterator_++);
25+
}
26+
27+
template<typename Frame>
28+
DiscreteTrajectorySegmentIterator<Frame>
29+
DiscreteTrajectorySegmentIterator<Frame>::operator--(int) { // NOLINT
30+
return DiscreteTrajectorySegmentIterator(segments_, iterator_--);
31+
}
32+
33+
template<typename Frame>
34+
internal_discrete_trajectory_segment::DiscreteTrajectorySegment<Frame> const&
35+
DiscreteTrajectorySegmentIterator<Frame>::operator*() const {
36+
return **iterator_;
37+
}
38+
39+
template<typename Frame>
40+
internal_discrete_trajectory_segment::DiscreteTrajectorySegment<Frame> const*
41+
DiscreteTrajectorySegmentIterator<Frame>::operator->() const {
42+
return iterator_->get();
43+
}
44+
45+
template<typename Frame>
46+
bool DiscreteTrajectorySegmentIterator<Frame>::operator==(
47+
DiscreteTrajectorySegmentIterator const& other) const {
48+
return segments_ == other.segments_ && iterator_ == other.iterator_;
49+
}
50+
51+
template<typename Frame>
52+
bool DiscreteTrajectorySegmentIterator<Frame>::operator!=(
53+
DiscreteTrajectorySegmentIterator const& other) const {
54+
return !operator==(other);
55+
}
56+
57+
template<typename Frame>
58+
DiscreteTrajectorySegmentIterator<Frame>::DiscreteTrajectorySegmentIterator(
59+
not_null<Segments const*> const segments,
60+
typename Segments::const_iterator iterator)
61+
: segments_(segments),
62+
iterator_(iterator) {}
63+
64+
template<typename Frame>
65+
DiscreteTrajectorySegmentIterator<Frame>
66+
DiscreteTrajectorySegmentIterator<Frame>::begin() const {
67+
return DiscreteTrajectorySegmentIterator(segments_, segments_->begin());
68+
}
69+
70+
template<typename Frame>
71+
DiscreteTrajectorySegmentIterator<Frame>
72+
DiscreteTrajectorySegmentIterator<Frame>::end() const {
73+
return DiscreteTrajectorySegmentIterator(segments_, segments_->end());
74+
}
75+
76+
} // namespace internal_discrete_trajectory_segment_iterator
77+
} // namespace physics
78+
} // namespace principia
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "physics/discrete_trajectory_segment_iterator.hpp"
2+
3+
#include <memory>
4+
#include <vector>
5+
6+
#include "base/not_null.hpp"
7+
#include "geometry/frame.hpp"
8+
#include "gmock/gmock.h"
9+
#include "gtest/gtest.h"
10+
#include "physics/discrete_trajectory_types.hpp"
11+
#include "physics/mock_discrete_trajectory_segment.hpp"
12+
13+
namespace principia {
14+
namespace physics {
15+
16+
using base::check_not_null;
17+
using base::not_null;
18+
using geometry::Frame;
19+
using ::testing::Return;
20+
21+
// We use a mock segment in this test to avoid having to go through a
22+
// complicated setup just to test the iterator.
23+
class DiscreteTrajectorySegmentIteratorTest : public ::testing::Test {
24+
protected:
25+
using World = Frame<enum class WorldTag>;
26+
27+
using Segments = internal_discrete_trajectory_types::Segments<World>;
28+
29+
DiscreteTrajectorySegmentIterator<World> MakeIterator(
30+
not_null<Segments const*> const segments,
31+
Segments::const_iterator const iterator) {
32+
return DiscreteTrajectorySegmentIterator<World>(segments, iterator);
33+
}
34+
};
35+
36+
TEST_F(DiscreteTrajectorySegmentIteratorTest, Basic) {
37+
auto owned_mock1 = std::make_unique<MockDiscreteTrajectorySegment<World>>();
38+
auto owned_mock2 = std::make_unique<MockDiscreteTrajectorySegment<World>>();
39+
auto owned_mock3 = std::make_unique<MockDiscreteTrajectorySegment<World>>();
40+
auto const& mock1 = *owned_mock1;
41+
auto const& mock2 = *owned_mock2;
42+
auto const& mock3 = *owned_mock3;
43+
44+
Segments segments;
45+
segments.push_back(std::move(owned_mock1));
46+
segments.push_back(std::move(owned_mock2));
47+
segments.push_back(std::move(owned_mock3));
48+
49+
EXPECT_CALL(mock1, size()).WillRepeatedly(Return(5));
50+
EXPECT_CALL(mock2, size()).WillRepeatedly(Return(1));
51+
EXPECT_CALL(mock3, size()).WillRepeatedly(Return(3));
52+
53+
{
54+
auto iterator = MakeIterator(check_not_null(&segments), segments.begin());
55+
EXPECT_EQ(5, iterator->size());
56+
auto const current = ++iterator;
57+
EXPECT_EQ(1, iterator->size());
58+
EXPECT_EQ(1, current->size());
59+
auto const previous = iterator++;
60+
EXPECT_EQ(3, iterator->size());
61+
EXPECT_EQ(1, previous->size());
62+
}
63+
{
64+
auto iterator = MakeIterator(check_not_null(&segments), segments.end());
65+
--iterator;
66+
EXPECT_EQ(3, (*iterator).size());
67+
auto const current = --iterator;
68+
EXPECT_EQ(1, (*iterator).size());
69+
EXPECT_EQ(1, (*current).size());
70+
auto const previous = iterator--;
71+
EXPECT_EQ(5, (*iterator).size());
72+
EXPECT_EQ(1, (*previous).size());
73+
}
74+
}
75+
76+
} // namespace physics
77+
} // namespace principia

physics/discrete_trajectory_types.hpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <memory>
55

66
#include "absl/container/btree_map.h"
7+
#include "base/macros.hpp"
78
#include "geometry/named_quantities.hpp"
89
#include "physics/degrees_of_freedom.hpp"
910

@@ -12,8 +13,9 @@
1213
namespace principia {
1314
namespace physics {
1415

15-
template<typename Frame>
16-
class DiscreteTrajectorySegment;
16+
FORWARD_DECLARE_FROM(discrete_trajectory_segment,
17+
TEMPLATE(typename Frame) class,
18+
DiscreteTrajectorySegment);
1719

1820
namespace internal_discrete_trajectory_types {
1921

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
5+
#include "gmock/gmock.h"
6+
#include "physics/discrete_trajectory_iterator.hpp"
7+
#include "physics/discrete_trajectory_segment.hpp"
8+
9+
namespace principia {
10+
namespace physics {
11+
12+
template<typename Frame>
13+
class MockDiscreteTrajectorySegment : public DiscreteTrajectorySegment<Frame> {
14+
public:
15+
MockDiscreteTrajectorySegment() = default;
16+
17+
MOCK_METHOD((typename internal_discrete_trajectory_types::Timeline<Frame>::
18+
const_iterator),
19+
timeline_begin, (),
20+
(const override));
21+
MOCK_METHOD((typename internal_discrete_trajectory_types::Timeline<Frame>::
22+
const_iterator),
23+
timeline_end, (),
24+
(const override));
25+
26+
MOCK_METHOD(std::int64_t, size, (), (const override));
27+
};
28+
29+
} // namespace physics
30+
} // namespace principia

0 commit comments

Comments
 (0)