Skip to content
Snippets Groups Projects
Unverified Commit c0b1ee06 authored by Sam Yates's avatar Sam Yates Committed by GitHub
Browse files

Fix event_generator constructor. (#1067)

* Guard `event_generator` implicit constructor with type test.
* Fix linking error from use of `empty_generator` by replacing pointers to `no_event` with nullptr.
* Clarify `regular_generator` semantics in comment.
* Add unit test for checking.

Fixes #1066
parent 58c4abef
No related branches found
No related tags found
No related merge requests found
......@@ -4,6 +4,7 @@
#include <cstdint>
#include <memory>
#include <random>
#include <type_traits>
#include <arbor/assert.hpp>
#include <arbor/common_types.hpp>
......@@ -61,18 +62,15 @@ using event_seq = std::pair<const spike_event*, const spike_event*>;
struct empty_generator {
void reset() {}
event_seq events(time_type, time_type) {
return {&no_event, &no_event};
return {nullptr, nullptr};
}
private:
static spike_event no_event;
};
class event_generator {
public:
event_generator(): event_generator(empty_generator()) {}
template <typename Impl>
template <typename Impl, std::enable_if_t<!std::is_same<std::decay_t<Impl>, event_generator>::value, int> = 0>
event_generator(Impl&& impl):
impl_(new wrap<Impl>(std::forward<Impl>(impl)))
{}
......@@ -128,6 +126,7 @@ private:
};
};
// Convenience routines for making schedule_generator:
// Generate events with a fixed target and weight according to
// a provided time schedule.
......@@ -161,7 +160,7 @@ private:
schedule sched_;
};
// Convenience routines for making schedule_generator:
// Generate events at integer multiples of dt that lie between tstart and tstop.
inline event_generator regular_generator(
cell_member_type target,
......
#include "../gtest.h"
#include <utility>
#include <arbor/event_generator.hpp>
#include <arbor/spike_event.hpp>
......@@ -15,8 +17,40 @@ namespace{
}
}
TEST(event_generators, assign_and_copy) {
event_generator gen = regular_generator({1, 2}, 5., 0.5, 0.75);
spike_event expected{{1, 2}, 0.75, 5.};
auto first = [](const event_seq& seq) {
if (seq.first==seq.second) throw std::runtime_error("no events");
return *seq.first;
};
ASSERT_EQ(expected, first(gen.events(0., 1.)));
gen.reset();
event_generator g1(gen);
EXPECT_EQ(expected, first(g1.events(0., 1.)));
event_generator g2;
g2 = gen;
EXPECT_EQ(expected, first(g2.events(0., 1.)));
const auto& const_gen = gen;
event_generator g3(const_gen);
EXPECT_EQ(expected, first(g3.events(0., 1.)));
event_generator g4;
g4 = gen;
EXPECT_EQ(expected, first(g4.events(0., 1.)));
event_generator g5(std::move(gen));
EXPECT_EQ(expected, first(g5.events(0., 1.)));
}
TEST(event_generators, regular) {
// make a regular generator that generates its first event at t=2ms and subsequent
// Make a regular generator that generates its first event at t=2ms and subsequent
// events regularly spaced 0.5 ms apart.
time_type t0 = 2.0;
time_type dt = 0.5;
......@@ -25,7 +59,7 @@ TEST(event_generators, regular) {
event_generator gen = regular_generator(target, weight, t0, dt);
// helper for building a set of
// Helper for building a set of expected events.
auto expected = [&] (std::vector<time_type> times) {
pse_vector events;
for (auto t: times) {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment