diff --git a/lmorpho/lmorpho.cpp b/lmorpho/lmorpho.cpp index 418b67ad5066a57d6e47011d64fdf43f603c7439..efe7615175257ac68fdb509fdf63b5002a43ac8e 100644 --- a/lmorpho/lmorpho.cpp +++ b/lmorpho/lmorpho.cpp @@ -15,7 +15,7 @@ namespace to = arb::to; using arb::util::optional; -using arb::util::nothing; +using arb::util::nullopt; using arb::util::just; const char* usage_str = @@ -31,7 +31,7 @@ const char* usage_str = "\n" "Generate artificial neuron morphologies based on L-system descriptions.\n" "\n" -"If a FILE arrgument contains a '%', then one file will be written for\n" +"If a FILE argument contains a '%', then one file will be written for\n" "each generated morphology, with the '%' replaced by the index of the\n" "morphology, starting from zero. Output for each morphology will otherwise\n" "be concatenated: SWC files will be headed by a comment line with the\n" @@ -89,10 +89,10 @@ int main(int argc, char** argv) { } std::minstd_rand g; - if (rng_seed) g.seed(rng_seed.get()); + if (rng_seed) g.seed(rng_seed.value()); - auto emit_swc = swc_file? just(swc_emitter(*swc_file, n_morph)): nothing; - auto emit_pvec = pvector_file? just(pvector_emitter(*pvector_file, n_morph)): nothing; + auto emit_swc = swc_file? just(swc_emitter(*swc_file, n_morph)): nullopt; + auto emit_pvec = pvector_file? just(pvector_emitter(*pvector_file, n_morph)): nullopt; for (int i=0; i<n_morph; ++i) { auto morph = generate_morphology(P, g); diff --git a/miniapps/miniapp/io.cpp b/miniapps/miniapp/io.cpp index b90d56bbae72f7722adff758e777e857744dc251..052bc5a52fb8c33b45bdb44f241f53af9e040472 100644 --- a/miniapps/miniapp/io.cpp +++ b/miniapps/miniapp/io.cpp @@ -105,7 +105,7 @@ static void update_option(util::optional<T>& opt, const nlohmann::json& j, const if (j.count(key)) { auto value = j[key]; if (value.is_null()) { - opt = util::nothing; + opt = util::nullopt; } else { opt = value.get<T>(); @@ -330,14 +330,14 @@ cl_options read_options(int argc, char** argv, bool allow_write) { fopts["probe_soma_only"] = options.probe_soma_only; fopts["trace_prefix"] = options.trace_prefix; if (options.trace_max_gid) { - fopts["trace_max_gid"] = options.trace_max_gid.get(); + fopts["trace_max_gid"] = options.trace_max_gid.value(); } else { fopts["trace_max_gid"] = nullptr; } fopts["trace_format"] = options.trace_format; if (options.morphologies) { - fopts["morphologies"] = options.morphologies.get(); + fopts["morphologies"] = options.morphologies.value(); } else { fopts["morphologies"] = nullptr; diff --git a/miniapps/miniapp/miniapp.cpp b/miniapps/miniapp/miniapp.cpp index b79b456b879ccf6680e63ba8bfa7bcfbbf571b20..cc34177b8eae7e55e92156a6beb7887bdceef893 100644 --- a/miniapps/miniapp/miniapp.cpp +++ b/miniapps/miniapp/miniapp.cpp @@ -208,7 +208,7 @@ std::unique_ptr<recipe> make_recipe(const io::cl_options& options, const probe_d if (options.morphologies) { std::cout << "loading morphologies...\n"; p.morphologies.clear(); - load_swc_morphology_glob(p.morphologies, options.morphologies.get()); + load_swc_morphology_glob(p.morphologies, options.morphologies.value()); std::cout << "loading morphologies: " << p.morphologies.size() << " loaded.\n"; } p.morphology_round_robin = options.morph_rr; diff --git a/miniapps/miniapp/miniapp_recipes.cpp b/miniapps/miniapp/miniapp_recipes.cpp index 9ab4cf3ae0a46f36fb769a34f3de7bdf0ae7fec1..017236d425a05820d39a64debfbb9cb146a46c06 100644 --- a/miniapps/miniapp/miniapp_recipes.cpp +++ b/miniapps/miniapp/miniapp_recipes.cpp @@ -91,7 +91,7 @@ public: // or a spikes from file. if (i == ncell_) { if (param_.input_spike_path) { - auto spike_times = io::get_parsed_spike_times_from_path(param_.input_spike_path.get()); + auto spike_times = io::get_parsed_spike_times_from_path(param_.input_spike_path.value()); return util::unique_any(dss_cell_description(spike_times)); } diff --git a/modcc/cprinter.cpp b/modcc/cprinter.cpp index 02a29a9b3c57f9db579cd3e91f973fc4ac02e974..bb855053f791acbe171c6423ebb1917fe12433e7 100644 --- a/modcc/cprinter.cpp +++ b/modcc/cprinter.cpp @@ -367,7 +367,7 @@ std::string CPrinter::emit_source() { text_.add_line("};"); text_.add_line(); text_.add_line("auto* info = util::table_lookup(field_tbl, id);"); - text_.add_line("return info? util::just(*info): util::nothing;"); + text_.add_line("return info? util::just(*info): util::nullopt;"); text_.decrease_indentation(); text_.add_line("}"); text_.add_line(); diff --git a/src/event_binner.cpp b/src/event_binner.cpp index 0b380bd4fd5263eb8a9ddf9c3c6aac0affc027ab..1b5d8c0a1f3bb2828f874cec768c3ababbb4a9ac 100644 --- a/src/event_binner.cpp +++ b/src/event_binner.cpp @@ -12,7 +12,7 @@ namespace arb { void event_binner::reset() { - last_event_time_ = util::nothing; + last_event_time_ = util::nullopt; } time_type event_binner::bin(time_type t, time_type t_min) { diff --git a/src/event_queue.hpp b/src/event_queue.hpp index 5675e1d1719e7e8f60bcea21e2bbbb4ea3607362..0d3fe5535954e7275408bb4b10c2c0bc91f867a2 100644 --- a/src/event_queue.hpp +++ b/src/event_queue.hpp @@ -73,12 +73,12 @@ public : // Return time t of head of queue if `t_until` > `t`. util::optional<event_time_type> time_if_before(const event_time_type& t_until) { if (queue_.empty()) { - return util::nothing; + return util::nullopt; } using ::arb::event_time; auto t = event_time(queue_.top()); - return t_until > t? util::just(t): util::nothing; + return t_until > t? util::just(t): util::nullopt; } // Generic conditional pop: pop and return head of queue if @@ -92,7 +92,7 @@ public : return ev; } else { - return util::nothing; + return util::nullopt; } } diff --git a/src/fvm_multicell.hpp b/src/fvm_multicell.hpp index 4a4dd52a03a5db1f501e4c094a018aebac73ef3e..3eb1fb1a73ebec1b077c5c6d5c484476d0b5e232 100644 --- a/src/fvm_multicell.hpp +++ b/src/fvm_multicell.hpp @@ -257,7 +257,7 @@ public: auto it = std::find_if( std::begin(mechanisms_), std::end(mechanisms_), [&name](const mechanism_ptr& m) {return m->name()==name;}); - return it==mechanisms_.end() ? util::nothing: util::just(*it); + return it==mechanisms_.end() ? util::nullopt: util::just(*it); } // diff --git a/src/hardware/affinity.cpp b/src/hardware/affinity.cpp index b36f34e8c05e6f3735d110b5fae64b87cbb42999..54b5f47b7e68ed1f7d455597b7ae521f6b97cf39 100644 --- a/src/hardware/affinity.cpp +++ b/src/hardware/affinity.cpp @@ -54,7 +54,7 @@ std::vector<int> get_affinity() { util::optional<std::size_t> num_cores() { auto cores = get_affinity(); if (cores.size()==0u) { - return util::nothing; + return util::nullopt; } return cores.size(); } diff --git a/src/model.cpp b/src/model.cpp index 87144a3461e63f9076ed4ec7aa1ef4c0326fa555..47519576dcbed4170f0201b9afc8f306bcedf47a 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -243,7 +243,7 @@ void model::set_local_spike_callback(spike_export_function export_callback) { util::optional<cell_size_type> model::local_cell_index(cell_gid_type gid) { auto it = gid_to_local_.find(gid); return it==gid_to_local_.end()? - util::nothing: + util::nullopt: util::optional<cell_size_type>(it->second); } diff --git a/src/segment.hpp b/src/segment.hpp index 66534669b928326ace2263b93acb3c6fcf2f2820..6c2e2e2b107b45b51fe22ab13c2eae026e80ee5f 100644 --- a/src/segment.hpp +++ b/src/segment.hpp @@ -83,13 +83,13 @@ public: util::optional<mechanism_spec&> mechanism(const std::string& name) { auto it = std::find_if(mechanisms_.begin(), mechanisms_.end(), [&](mechanism_spec& m) { return m.name()==name; }); - return it==mechanisms_.end()? util::nothing: util::just(*it); + return it==mechanisms_.end()? util::nullopt: util::just(*it); } void add_mechanism(mechanism_spec mech) { auto m = mechanism(mech.name()); if (m) { - m.get() = std::move(mech); + *m = std::move(mech); } else { mechanisms_.push_back(std::move(mech)); diff --git a/src/threading/threading.cpp b/src/threading/threading.cpp index 35ebf467872f29ae8b362770a6c7c47179ff37f2..c1cd5f2f98c2ee3a7e564794d7f01462d9a645e0 100644 --- a/src/threading/threading.cpp +++ b/src/threading/threading.cpp @@ -40,7 +40,7 @@ util::optional<size_t> get_env_num_threads() { // If the selected var is unset set the number of threads to // the hint given by the standard library if (!str) { - return util::nothing; + return util::nullopt; } auto nthreads = std::strtoul(str, nullptr, 10); diff --git a/src/tinyopt.hpp b/src/tinyopt.hpp index c90ba789bd96079694202bdaf50a0d3abba4419c..ca4366677f1a940075695382735f735f7c05c40f 100644 --- a/src/tinyopt.hpp +++ b/src/tinyopt.hpp @@ -42,7 +42,7 @@ struct default_parser { V v; std::istringstream stream(text); stream >> v; - return stream? util::just(v): util::nothing; + return stream? util::just(v): util::nullopt; } }; @@ -58,7 +58,7 @@ public: for (const auto& p: map_) { if (text==p.first) return p.second; } - return util::nothing; + return util::nullopt; } }; @@ -72,7 +72,7 @@ util::optional<V> parse_opt(char **& argp, char shortopt, const char* longopt=nu const char* arg = argp[0]; if (!arg || arg[0]!='-') { - return util::nothing; + return util::nullopt; } std::string text; @@ -91,7 +91,7 @@ util::optional<V> parse_opt(char **& argp, char shortopt, const char* longopt=nu argp += 1; } else { - return util::nothing; + return util::nullopt; } } else if (shortopt && arg[1]==shortopt && arg[2]==0) { @@ -100,7 +100,7 @@ util::optional<V> parse_opt(char **& argp, char shortopt, const char* longopt=nu argp += 2; } else { - return util::nothing; + return util::nullopt; } auto v = parse(text); @@ -111,7 +111,7 @@ util::optional<V> parse_opt(char **& argp, char shortopt, const char* longopt=nu util::optional<void> parse_opt(char **& argp, char shortopt, const char* longopt) { if (!*argp || *argp[0]!='-') { - return util::nothing; + return util::nullopt; } else if (argp[0][1]=='-' && longopt && !std::strcmp(argp[0]+2, longopt)) { ++argp; @@ -122,7 +122,7 @@ util::optional<void> parse_opt(char **& argp, char shortopt, const char* longopt return true; } else { - return util::nothing; + return util::nullopt; } } diff --git a/src/util/hostname.cpp b/src/util/hostname.cpp index 85152e903184253b6e2e959f4f20978d7a72c5e4..a88316d9fd5c2a0f5f1c66fe1da08b092c1f171b 100644 --- a/src/util/hostname.cpp +++ b/src/util/hostname.cpp @@ -20,13 +20,13 @@ util::optional<std::string> hostname() { char name[256]; auto result = gethostname(name, sizeof(name)); if (result) { - return util::nothing; + return util::nullopt; } return std::string(name); } #else util::optional<std::string> hostname() { - return util::nothing; + return util::nullopt; } #endif diff --git a/src/util/optional.hpp b/src/util/optional.hpp index f674f8f3a42669c008a6a9b53aa1fc65a7ef863b..6166d8e49c6b5a64dad5ff89ff1131040773b913 100644 --- a/src/util/optional.hpp +++ b/src/util/optional.hpp @@ -1,18 +1,39 @@ #pragma once -/* An option class with a monadic interface. +/* An option class supporting a subset of C++17 std::optional functionality. * - * The std::option<T> class was proposed for inclusion into C++14, but was - * ultimately rejected. (See N3672 proposal for details.) This class offers - * similar functionality, namely a class that can represent a value (or - * reference), or nothing at all. + * Difference from C++17 std::optional: * - * In addition, this class offers monadic and monoidal bindings, allowing - * the chaining of operations any one of which might represent failure with - * an unset optional value. + * Missing functionality (to be added as required): * - * One point of difference between the proposal N3672 and this implementation - * is the lack of constexpr versions of the methods and constructors. + * 1. `constexpr` constructors. + * + * 2. Comparison operators other than `operator==`. + * + * 3. `std::hash` overload. + * + * 4. `swap()` method and ADL-available `swap()` function. + * + * 5. In-place construction with `std::in_place_t` tags or equivalent. + * + * 5. No `make_optional` function (but see `just` below). + * + * Additional/differing functionality: + * + * 1. Optional references. + * + * `util::optional<T&>` acts as a value-like wrapper about a possible + * reference of type T&. Methods such as `value()` or `value_or()` + * return this reference. + * + * 2. Optional void. + * + * Included primarily for ease of generic programming with `optional`. + * + * 3. `util::just` + * + * This function acts like the value-constructing `std::make_optional<T>(T&&)`, + * except that it will return an optional<T&> if given an lvalue T as an argument. */ #include <type_traits> @@ -37,8 +58,8 @@ struct optional_unset_error: std::runtime_error { {} }; -struct nothing_t {}; -constexpr nothing_t nothing{}; +struct nullopt_t {}; +constexpr nullopt_t nullopt{}; namespace detail { template <typename Y> @@ -83,6 +104,8 @@ namespace detail { protected: using data_type = util::uninitialized<X>; + using rvalue_reference = typename data_type::rvalue_reference; + using const_rvalue_reference = typename data_type::const_rvalue_reference; public: using reference = typename data_type::reference; @@ -106,6 +129,12 @@ namespace detail { reference ref() { return data.ref(); } const_reference ref() const { return data.cref(); } + void assert_set() const { + if (!set) { + throw optional_unset_error(); + } + } + public: ~optional_base() { if (set) { @@ -119,20 +148,6 @@ namespace detail { reference operator*() { return ref(); } const_reference operator*() const { return ref(); } - reference get() { - if (!set) { - throw optional_unset_error(); - } - return ref(); - } - - const_reference get() const { - if (!set) { - throw optional_unset_error(); - } - return ref(); - } - explicit operator bool() const { return set; } template <typename Y> @@ -151,60 +166,6 @@ namespace detail { } set = false; } - - template <typename F> - auto bind(F&& f) -> lift_type_t<decltype(data.apply(std::forward<F>(f)))> { - using F_result_type = decltype(data.apply(std::forward<F>(f))); - using result_type = lift_type_t<F_result_type>; - - if (!set) { - return result_type(); - } - - return bind_impl<result_type, std::is_void<F_result_type>::value>:: - bind(data, std::forward<F>(f)); - } - - template <typename F> - auto bind(F&& f) const -> lift_type_t<decltype(data.apply(std::forward<F>(f)))> { - using F_result_type = decltype(data.apply(std::forward<F>(f))); - using result_type = lift_type_t<F_result_type>; - - if (!set) { - return result_type(); - } - - return bind_impl<result_type, std::is_void<F_result_type>::value>:: - bind(data, std::forward<F>(f)); - } - - template <typename F> - auto operator>>(F&& f) -> decltype(this->bind(std::forward<F>(f))) { - return bind(std::forward<F>(f)); - } - - template <typename F> - auto operator>>(F&& f) const -> decltype(this->bind(std::forward<F>(f))) { - return bind(std::forward<F>(f)); - } - - private: - template <typename R, bool F_void_return> - struct bind_impl { - template <typename DT, typename F> - static R bind(DT& d, F&& f) { - return R(d.apply(std::forward<F>(f))); - } - }; - - template <typename R> - struct bind_impl<R, true> { - template <typename DT, typename F> - static R bind(DT& d, F&& f) { - d.apply(std::forward<F>(f)); - return R(true); - } - }; }; // type utilities @@ -227,9 +188,10 @@ struct optional: detail::optional_base<X> { using base::ref; using base::reset; using base::data; + using base::assert_set; optional() noexcept: base() {} - optional(nothing_t) noexcept: base() {} + optional(nullopt_t) noexcept: base() {} optional(const X& x) noexcept(std::is_nothrow_copy_constructible<X>::value): base(true, x) {} @@ -250,7 +212,7 @@ struct optional: detail::optional_base<X> { optional(optional<T>&& ot) noexcept(std::is_nothrow_constructible<X, T&&>::value): base(ot.set, std::move(ot.ref())) {} - optional& operator=(nothing_t) { + optional& operator=(nullopt_t) { reset(); return *this; } @@ -310,6 +272,32 @@ struct optional: detail::optional_base<X> { } return *this; } + + X& value() & { + return assert_set(), ref(); + } + + const X& value() const& { + return assert_set(), ref(); + } + + X&& value() && { + return assert_set(), std::move(ref()); + } + + const X&& value() const&& { + return assert_set(), std::move(ref()); + } + + template <typename T> + X value_or(T&& alternative) const& { + return set? value(): static_cast<X>(std::forward<T>(alternative)); + } + + template <typename T> + X value_or(T&& alternative) && { + return set? std::move(value()): static_cast<X>(std::forward<T>(alternative)); + } }; template <typename X> @@ -319,15 +307,16 @@ struct optional<X&>: detail::optional_base<X&> { using base::ref; using base::data; using base::reset; + using base::assert_set; optional() noexcept: base() {} - optional(nothing_t) noexcept: base() {} + optional(nullopt_t) noexcept: base() {} optional(X& x) noexcept: base(true, x) {} template <typename T> optional(optional<T&>& ot) noexcept: base(ot.set, ot.ref()) {} - optional& operator=(nothing_t) { + optional& operator=(nullopt_t) { reset(); return *this; } @@ -343,24 +332,39 @@ struct optional<X&>: detail::optional_base<X&> { optional& operator=(optional<Y&>& o) { set = o.set; if (o.set) { - data.construct(o.get()); + data.construct(o.value()); } return *this; } -}; + X& value() { + return assert_set(), ref(); + } + + const X& value() const { + return assert_set(), ref(); + } + + template <typename T> + X& value_or(T& alternative) { + return set? ref(): static_cast<X&>(alternative); + } -/* special case for optional<void>, used as e.g. the result of - * binding to a void function */ + template <typename T> + const X& value_or(const T& alternative) const { + return set? ref(): static_cast<const X&>(alternative); + } +}; template <> struct optional<void>: detail::optional_base<void> { using base = detail::optional_base<void>; + using base::assert_set; using base::set; using base::reset; optional(): base() {} - optional(nothing_t): base() {} + optional(nullopt_t): base() {} template <typename T> optional(T): base(true, true) {} @@ -368,7 +372,7 @@ struct optional<void>: detail::optional_base<void> { template <typename T> optional(const optional<T>& o): base(o.set, true) {} - optional& operator=(nothing_t) { + optional& operator=(nullopt_t) { reset(); return *this; } @@ -391,36 +395,12 @@ struct optional<void>: detail::optional_base<void> { bool operator==(const optional<void>& o) const { return (set && o.set) || (!set && !o.set); } -}; - - -template <typename A, typename B> -typename std::enable_if< - detail::is_optional<A>::value || detail::is_optional<B>::value, - optional< - typename std::common_type< - detail::wrapped_type_t<A>, - detail::wrapped_type_t<B> - >::type - > ->::type -operator|(A&& a, B&& b) { - return detail::decay_bool(a) ? a : b; -} -template <typename A, typename B> -typename std::enable_if< - detail::is_optional<A>::value || detail::is_optional<B>::value, - optional<detail::wrapped_type_t<B>> ->::type -operator&(A&& a, B&& b) { - using result_type = optional<detail::wrapped_type_t<B>>; - return a ? b: result_type(); -} + void value() const { assert_set(); } -inline optional<void> provided(bool condition) { - return condition ? optional<void>(true) : optional<void>(); -} + template <typename T> + void value_or(T) const {} // nop +}; template <typename X> optional<X> just(X&& x) { diff --git a/src/util/uninitialized.hpp b/src/util/uninitialized.hpp index b5653939cd8f47ac1a231c48d8b243821eb5a198..a1c42d55da9cac9970105480780e6d916b4ff071 100644 --- a/src/util/uninitialized.hpp +++ b/src/util/uninitialized.hpp @@ -32,6 +32,8 @@ public: using const_pointer = const X*; using reference = X&; using const_reference= const X&; + using rvalue_reference = X&&; + using const_rvalue_reference= const X&&; pointer ptr() { // COMPAT: xlC 13.1.4 workaround: @@ -92,6 +94,8 @@ public: using const_pointer = const X*; using reference = X&; using const_reference = const X&; + using rvalue_reference = X&; + using const_rvalue_reference= const X&; pointer ptr() { return data; } const_pointer cptr() const { return data; } @@ -101,18 +105,6 @@ public: void construct(X& x) { data = &x; } void destruct() {} - - // Apply the one-parameter functor F to the value by reference. - template <typename F> - result_of_t<F(reference)> apply(F&& f) { - return f(ref()); - } - - // Apply the one-parameter functor F to the value by const reference. - template <typename F> - result_of_t<F(const_reference)> apply(F&& f) const { - return f(cref()); - } }; /* Wrap a void type in an uninitialized template. @@ -126,6 +118,8 @@ public: using const_pointer = const void*; using reference = void; using const_reference = void; + using rvalue_reference = void; + using const_rvalue_reference = void; pointer ptr() { return nullptr; } const_pointer cptr() const { return nullptr; } @@ -137,10 +131,6 @@ public: void construct(...) {} // No operation. void destruct() {} - - // Equivalent to f() - template <typename F> - result_of_t<F()> apply(F&& f) const { return f(); } }; } // namespace util diff --git a/tests/unit/common.hpp b/tests/unit/common.hpp index 445f59928abe7f5d74c2f77b26422b71320bb1af..70eace9a79c0500ceddf4658b0eae5f115c7ee39 100644 --- a/tests/unit/common.hpp +++ b/tests/unit/common.hpp @@ -5,13 +5,22 @@ * more than one unit test. */ -#include <utility> #include <cmath> +#include <string> +#include <utility> #include "../gtest.h" namespace testing { +// string ctor suffix (until C++14!) + +namespace string_literals { + inline std::string operator ""_s(const char* s, std::size_t n) { + return std::string(s, n); + } +} + // sentinel for use with range-related tests struct null_terminated_t { diff --git a/tests/unit/test_any.cpp b/tests/unit/test_any.cpp index 12aa3598258b1a6960065aa06166ae0e7f48a82f..cce483f67f025753b2815ced083c6f076b305a7d 100644 --- a/tests/unit/test_any.cpp +++ b/tests/unit/test_any.cpp @@ -10,6 +10,7 @@ #include <typeinfo> using namespace arb; +using namespace testing::string_literals; TEST(any, copy_construction) { util::any any_int(2); @@ -75,7 +76,7 @@ TEST(any, type) { using util::any; any anyi(42); - any anys(std::string("hello")); + any anys("hello"_s); any anyv(std::vector<int>{1, 2, 3}); any any0; @@ -141,7 +142,7 @@ TEST(any, any_cast_ptr) { auto ptr_i = util::any_cast<int>(&ai); EXPECT_EQ(*ptr_i, 42); - util::any as(std::string("hello")); + util::any as("hello"_s); auto ptr_s = util::any_cast<std::string>(&as); EXPECT_EQ(*ptr_s, "hello"); @@ -303,7 +304,7 @@ TEST(any, make_any) { // create a string from const char* auto a = make_any<std::string>("hello"); - EXPECT_EQ(any_cast<std::string>(a), std::string("hello")); + EXPECT_EQ(any_cast<std::string>(a), "hello"_s); } // test that we make_any correctly forwards rvalue arguments to the constructor diff --git a/tests/unit/test_fvm_multi.cpp b/tests/unit/test_fvm_multi.cpp index 1d2f940858be2ffeffb3b69d88947258c0438dec..aa65c7bbf438ff56d690da1c57b680b4e2ba835c 100644 --- a/tests/unit/test_fvm_multi.cpp +++ b/tests/unit/test_fvm_multi.cpp @@ -57,7 +57,7 @@ TEST(fvm_multi, init) const auto m = cell.model(); EXPECT_EQ(m.tree.num_segments(), 2u); - auto& soma_hh = (cell.soma()->mechanism("hh")).get(); + auto& soma_hh = (cell.soma()->mechanism("hh")).value(); soma_hh.set("gnabar", 0.12); soma_hh.set("gkbar", 0.036); @@ -200,7 +200,7 @@ TEST(fvm_multi, stimulus) auto ref = fvcell.find_mechanism("stimulus"); ASSERT_TRUE(ref) << "no stimuli retrieved from lowered fvm cell: expected 2"; - auto& stims = ref.get(); + auto& stims = ref.value(); EXPECT_EQ(stims->size(), 2u); auto I = fvcell.current(); diff --git a/tests/unit/test_optional.cpp b/tests/unit/test_optional.cpp index 73384f1b4d009643c0ebc103b98dc5c75c8bfc33..d19fbbc2720fb32ef1bd0caee81100b0deb0eeba 100644 --- a/tests/unit/test_optional.cpp +++ b/tests/unit/test_optional.cpp @@ -1,114 +1,116 @@ -#include <typeinfo> -#include <array> #include <algorithm> +#include <array> +#include <string> +#include <typeinfo> #include "../gtest.h" #include "util/optional.hpp" #include "common.hpp" using namespace arb::util; +using namespace testing::string_literals; -TEST(optionalm,ctors) { - optional<int> a,b(3),c=b,d=4; +TEST(optional, ctors) { + optional<int> a, b(3), c = b, d = 4; ASSERT_FALSE((bool)a); ASSERT_TRUE((bool)b); ASSERT_TRUE((bool)c); ASSERT_TRUE((bool)d); - EXPECT_EQ(3,b.get()); - EXPECT_EQ(3,c.get()); - EXPECT_EQ(4,d.get()); + EXPECT_EQ(3, b.value()); + EXPECT_EQ(3, c.value()); + EXPECT_EQ(4, d.value()); } -TEST(optionalm,unset_throw) { +TEST(optional, unset_throw) { optional<int> a; - int check=10; + int check = 10; try { - a.get(); + a.value(); } catch (optional_unset_error& e) { ++check; } - EXPECT_EQ(11,check); + EXPECT_EQ(11, check); - check=20; - a=2; + check = 20; + a = 2; try { - a.get(); + a.value(); } catch (optional_unset_error& e) { ++check; } - EXPECT_EQ(20,check); + EXPECT_EQ(20, check); - check=30; + check = 30; a.reset(); try { - a.get(); + a.value(); } catch (optional_unset_error& e) { ++check; } - EXPECT_EQ(31,check); + EXPECT_EQ(31, check); } -TEST(optionalm,deref) { +TEST(optional, deref) { struct foo { int a; explicit foo(int a_): a(a_) {} double value() { return 3.0*a; } }; - optional<foo> f=foo(2); - EXPECT_EQ(6.0,f->value()); - EXPECT_EQ(2,(*f).a); + optional<foo> f = foo(2); + EXPECT_EQ(6.0, f->value()); + EXPECT_EQ(2, (*f).a); } -TEST(optionalm,ctor_conv) { - optional<std::array<int,3>> x{{1,2,3}}; - EXPECT_EQ(3u,x->size()); +TEST(optional, ctor_conv) { + optional<std::array<int, 3>> x{{1, 2, 3}}; + EXPECT_EQ(3u, x->size()); } -TEST(optionalm,ctor_ref) { - int v=10; +TEST(optional, ctor_ref) { + int v = 10; optional<int&> a(v); - EXPECT_EQ(10,a.get()); - v=20; - EXPECT_EQ(20,a.get()); + EXPECT_EQ(10, a.value()); + v = 20; + EXPECT_EQ(20, a.value()); - optional<int&> b(a),c=b,d=v; - EXPECT_EQ(&(a.get()),&(b.get())); - EXPECT_EQ(&(a.get()),&(c.get())); - EXPECT_EQ(&(a.get()),&(d.get())); + optional<int&> b(a), c = b, d = v; + EXPECT_EQ(&(a.value()), &(b.value())); + EXPECT_EQ(&(a.value()), &(c.value())); + EXPECT_EQ(&(a.value()), &(d.value())); } -TEST(optionalm,assign_returns) { - optional<int> a=3; +TEST(optional, assign_returns) { + optional<int> a = 3; - auto b=(a=4); - EXPECT_EQ(typeid(optional<int>),typeid(b)); + auto b = (a = 4); + EXPECT_EQ(typeid(optional<int>), typeid(b)); - auto bp=&(a=4); - EXPECT_EQ(&a,bp); + auto bp = &(a = 4); + EXPECT_EQ(&a, bp); - auto b2=(a=optional<int>(10)); - EXPECT_EQ(typeid(optional<int>),typeid(b2)); + auto b2 = (a = optional<int>(10)); + EXPECT_EQ(typeid(optional<int>), typeid(b2)); - auto bp2=&(a=4); - EXPECT_EQ(&a,bp2); + auto bp2 = &(a = 4); + EXPECT_EQ(&a, bp2); - auto b3=(a=nothing); - EXPECT_EQ(typeid(optional<int>),typeid(b3)); + auto b3 = (a = nullopt); + EXPECT_EQ(typeid(optional<int>), typeid(b3)); - auto bp3=&(a=4); - EXPECT_EQ(&a,bp3); + auto bp3 = &(a = 4); + EXPECT_EQ(&a, bp3); } -TEST(optionalm,assign_reference) { - double a=3.0; +TEST(optional, assign_reference) { + double a = 3.0; optional<double&> ar; optional<double&> br; @@ -117,234 +119,169 @@ TEST(optionalm,assign_reference) { *ar = 5.0; EXPECT_EQ(5.0, a); - auto& check_rval=(br=ar); + auto& check_rval = (br = ar); EXPECT_TRUE(br); EXPECT_EQ(&br, &check_rval); *br = 7.0; EXPECT_EQ(7.0, a); - auto& check_rval2=(br=nothing); + auto& check_rval2 = (br = nullopt); EXPECT_FALSE(br); EXPECT_EQ(&br, &check_rval2); } -TEST(optionalm,ctor_nomove) { +TEST(optional, ctor_nomove) { using nomove = testing::nomove<int>; optional<nomove> a(nomove(3)); - EXPECT_EQ(nomove(3),a.get()); + EXPECT_EQ(nomove(3), a.value()); optional<nomove> b; - b=a; - EXPECT_EQ(nomove(3),b.get()); + b = a; + EXPECT_EQ(nomove(3), b.value()); - b=optional<nomove>(nomove(4)); - EXPECT_EQ(nomove(4),b.get()); + b = optional<nomove>(nomove(4)); + EXPECT_EQ(nomove(4), b.value()); } -TEST(optionalm,ctor_nocopy) { +TEST(optional, ctor_nocopy) { using nocopy = testing::nocopy<int>; optional<nocopy> a(nocopy(5)); - EXPECT_EQ(nocopy(5),a.get()); + EXPECT_EQ(nocopy(5), a.value()); nocopy::reset_counts(); optional<nocopy> b(std::move(a)); - EXPECT_EQ(nocopy(5),b.get()); - EXPECT_EQ(0,a.get().value); + EXPECT_EQ(nocopy(5), b.value()); + EXPECT_EQ(0, a.value().value); EXPECT_EQ(1, nocopy::move_ctor_count); EXPECT_EQ(0, nocopy::move_assign_count); nocopy::reset_counts(); - b=optional<nocopy>(nocopy(6)); - EXPECT_EQ(nocopy(6),b.get()); + b = optional<nocopy>(nocopy(6)); + EXPECT_EQ(nocopy(6), b.value()); EXPECT_EQ(1, nocopy::move_ctor_count); EXPECT_EQ(1, nocopy::move_assign_count); -} + nocopy::reset_counts(); + nocopy v = optional<nocopy>(nocopy(9)).value(); + EXPECT_EQ(2, nocopy::move_ctor_count); + EXPECT_EQ(nocopy(9), v.value); -static optional<double> odd_half(int n) { - optional<double> h; - if (n%2==1) h=n/2.0; - return h; + const optional<nocopy> ccheck(nocopy(1)); + EXPECT_TRUE(std::is_rvalue_reference<decltype(std::move(ccheck).value())>::value); + EXPECT_TRUE(std::is_const<std::remove_reference<decltype(std::move(ccheck).value())>::type>::value); } -TEST(optionalm,bind) { - optional<int> a; - auto b=a.bind(odd_half); - - EXPECT_EQ(typeid(optional<double>),typeid(b)); +TEST(optional, value_or) { + optional<double> x = 3; + EXPECT_EQ(3., x.value_or(5)); - a=10; - b=a.bind(odd_half); - EXPECT_FALSE((bool)b); + x = nullopt; + EXPECT_EQ(5., x.value_or(5)); - a=11; - b=a.bind(odd_half); - EXPECT_TRUE((bool)b); - EXPECT_EQ(5.5,b.get()); + // `value_or` returns T for optional<T>: + struct check_conv { + bool value = false; + explicit check_conv(bool value): value(value) {} - b=a >> odd_half >> [](double x) { return (int)x; } >> odd_half; - EXPECT_TRUE((bool)b); - EXPECT_EQ(2.5,b.get()); -} + explicit operator std::string() const { + return value? "true": "false"; + } + }; + check_conv cc{true}; -TEST(optionalm,void) { - optional<void> a,b(true),c(a),d=b,e(false),f(nothing); + optional<std::string> present = "present"_s; + optional<std::string> absent; // nullopt - EXPECT_FALSE((bool)a); - EXPECT_TRUE((bool)b); - EXPECT_FALSE((bool)c); - EXPECT_TRUE((bool)d); - EXPECT_TRUE((bool)e); - EXPECT_FALSE((bool)f); + auto result = present.value_or(cc); + EXPECT_EQ(typeid(std::string), typeid(result)); + EXPECT_EQ("present"_s, result); - auto x=a >> []() { return 1; }; - EXPECT_FALSE((bool)x); + result = absent.value_or(cc); + EXPECT_EQ("true"_s, result); - x=b >> []() { return 1; }; - EXPECT_TRUE((bool)x); - EXPECT_EQ(1,x.get()); + // Check move semantics in argument: - auto& check_rval=(b=nothing); - EXPECT_FALSE((bool)b); - EXPECT_EQ(&b,&check_rval); -} + using nocopy = testing::nocopy<int>; -TEST(optionalm,bind_to_void) { - optional<int> a,b(3); + nocopy::reset_counts(); + nocopy z1 = optional<nocopy>().value_or(nocopy(7)); - int call_count=0; - auto vf=[&call_count](int i) -> void { ++call_count; }; + EXPECT_EQ(7, z1.value); + EXPECT_EQ(1, nocopy::move_ctor_count); - auto x=a >> vf; - EXPECT_EQ(typeid(optional<void>),typeid(x)); - EXPECT_FALSE((bool)x); - EXPECT_EQ(0,call_count); + nocopy::reset_counts(); + nocopy z2 = optional<nocopy>(nocopy(3)).value_or(nocopy(7)); - call_count=0; - x=b >> vf; - EXPECT_TRUE((bool)x); - EXPECT_EQ(1,call_count); + EXPECT_EQ(3, z2.value); + EXPECT_EQ(2, nocopy::move_ctor_count); } -TEST(optionalm,bind_to_optional_void) { - optional<int> a,b(3),c(4); +TEST(optional, ref_value_or) { + double a = 2.0; + double b = 3.0; - int count=0; - auto count_if_odd=[&count](int i) { - return i%2?(++count,optional<void>(true)):optional<void>(); - }; + optional<double&> x = a; + double& ref1 = x.value_or(b); - auto x=a >> count_if_odd; - EXPECT_EQ(typeid(optional<void>),typeid(x)); - EXPECT_FALSE((bool)x); - EXPECT_EQ(0,count); + EXPECT_EQ(2., ref1); - count=0; - x=b >> count_if_odd; - EXPECT_TRUE((bool)x); - EXPECT_EQ(1,count); + x = nullopt; + double& ref2 = x.value_or(b); - count=0; - x=c >> count_if_odd; - EXPECT_FALSE((bool)x); - EXPECT_EQ(0,count); -} + EXPECT_EQ(3., ref2); + + ref1 = 12.; + ref2 = 13.; + EXPECT_EQ(12., a); + EXPECT_EQ(13., b); -TEST(optionalm,bind_with_ref) { - optional<int> a=10; - a >> [](int& v) { ++v; }; - EXPECT_EQ(11,*a); + const optional<double&> cx = x; + auto& ref3 = cx.value_or(b); + EXPECT_TRUE(std::is_const<std::remove_reference<decltype(ref3)>::type>::value); + EXPECT_EQ(&b, &ref3); } -struct check_cref { - int operator()(const int&) { return 10; } - int operator()(int&) { return 11; } -}; +TEST(optional, void) { + optional<void> a, b(true), c(a), d = b, e(false), f(nullopt); -TEST(optionalm,bind_constness) { - check_cref checker; - optional<int> a=1; - int v=*(a >> checker); - EXPECT_EQ(11,v); + EXPECT_FALSE((bool)a); + EXPECT_TRUE((bool)b); + EXPECT_FALSE((bool)c); + EXPECT_TRUE((bool)d); + EXPECT_TRUE((bool)e); + EXPECT_FALSE((bool)f); - const optional<int> b=1; - v=*(b >> checker); - EXPECT_EQ(10,v); + auto& check_rval = (b = nullopt); + EXPECT_FALSE((bool)b); + EXPECT_EQ(&b, &check_rval); } - -TEST(optionalm,conversion) { - optional<double> a(3),b=5; +TEST(optional, conversion) { + optional<double> a(3), b = 5; EXPECT_TRUE((bool)a); EXPECT_TRUE((bool)b); - EXPECT_EQ(3.0,a.get()); - EXPECT_EQ(5.0,b.get()); + EXPECT_EQ(3.0, a.value()); + EXPECT_EQ(5.0, b.value()); optional<int> x; optional<double> c(x); - optional<double> d=optional<int>(); + optional<double> d = optional<int>(); EXPECT_FALSE((bool)c); EXPECT_FALSE((bool)d); - - auto doubler=[](double x) { return x*2; }; - auto y=optional<int>(3) >> doubler; - EXPECT_TRUE((bool)y); - EXPECT_EQ(6.0,y.get()); -} - -TEST(optionalm,or_operator) { - optional<const char *> default_msg="default"; - auto x=(char *)0 | default_msg; - EXPECT_TRUE((bool)x); - EXPECT_STREQ("default",x.get()); - - auto y="something" | default_msg; - EXPECT_TRUE((bool)y); - EXPECT_STREQ("something",y.get()); - - optional<int> a(1),b,c(3); - EXPECT_EQ(1,*(a|b|c)); - EXPECT_EQ(1,*(a|c|b)); - EXPECT_EQ(1,*(b|a|c)); - EXPECT_EQ(3,*(b|c|a)); - EXPECT_EQ(3,*(c|a|b)); - EXPECT_EQ(3,*(c|b|a)); -} - -TEST(optionalm,and_operator) { - optional<int> a(1); - optional<double> b(2.0); - - auto ab=a&b; - auto ba=b&a; - - EXPECT_EQ(typeid(ab),typeid(b)); - EXPECT_EQ(typeid(ba),typeid(a)); - EXPECT_EQ(2.0,*ab); - EXPECT_EQ(1,*ba); - - auto zb=false & b; - EXPECT_EQ(typeid(zb),typeid(b)); - EXPECT_FALSE((bool)zb); - - auto b3=b & 3; - EXPECT_EQ(typeid(b3),typeid(optional<int>)); - EXPECT_TRUE((bool)b3); - EXPECT_EQ(3,*b3); } -TEST(optionalm,provided) { - std::array<int,3> qs={1,0,3}; - std::array<int,3> ps={14,14,14}; - std::array<int,3> rs; +TEST(optional, just) { + int x = 3; - std::transform(ps.begin(),ps.end(),qs.begin(),rs.begin(), - [](int p,int q) { return *( provided(q!=0) >> [=]() { return p/q; } | -1 ); }); + optional<int&> o1 = just(x); + optional<int> o2 = just(x); - EXPECT_EQ(14,rs[0]); - EXPECT_EQ(-1,rs[1]); - EXPECT_EQ(4,rs[2]); + o1.value() = 4; + optional<int> o3 = just(x); + EXPECT_EQ(4, o1.value()); + EXPECT_EQ(3, o2.value()); + EXPECT_EQ(4, o3.value()); } diff --git a/tests/unit/test_range.cpp b/tests/unit/test_range.cpp index fb9012d3cbacd4805aae69a223f56f4c6e241a9b..09e22c43ebd6d961b323065999951d267df611f2 100644 --- a/tests/unit/test_range.cpp +++ b/tests/unit/test_range.cpp @@ -23,6 +23,8 @@ #include "common.hpp" using namespace arb; + +using namespace testing::string_literals; using testing::null_terminated; using testing::nocopy; using testing::nomove; @@ -418,11 +420,11 @@ TEST(range, sort) { // simple sort util::sort(util::strict_view(cstr_range)); - EXPECT_EQ(std::string("dhowy"), cstr); + EXPECT_EQ("dhowy"_s, cstr); // reverse sort by transform c to -c util::sort_by(util::strict_view(cstr_range), [](char c) { return -c; }); - EXPECT_EQ(std::string("ywohd"), cstr); + EXPECT_EQ("ywohd"_s, cstr); // stable sort: move capitals to front, numbers to back auto rank = [](char c) { @@ -433,7 +435,7 @@ TEST(range, sort) { auto mixed_range = util::make_range(std::begin(mixed), null_terminated); util::stable_sort_by(util::strict_view(mixed_range), rank); - EXPECT_EQ(std::string("HELLOthere54321"), mixed); + EXPECT_EQ("HELLOthere54321"_s, mixed); // sort with user-provided less comparison function @@ -453,7 +455,7 @@ TEST(range, sum_by) { auto result = util::sum_by(words, prepend_); EXPECT_EQ("_fish_cakes_!", result); - result = util::sum_by(words, prepend_, std::string("tasty")); + result = util::sum_by(words, prepend_, "tasty"_s); EXPECT_EQ("tasty_fish_cakes_!", result); auto count = util::sum_by(words, [](const std::string &x) { return x.size(); }); @@ -475,10 +477,10 @@ TEST(range, all_of_any_of) { auto pred = [](char c) { return c=='x'? throw c:c<'5'; }; // all - EXPECT_TRUE(util::all_of(std::string(), pred)); - EXPECT_TRUE(util::all_of(std::string("1234"), pred)); - EXPECT_FALSE(util::all_of(std::string("12345"), pred)); - EXPECT_FALSE(util::all_of(std::string("12345x"), pred)); + EXPECT_TRUE(util::all_of(""_s, pred)); + EXPECT_TRUE(util::all_of("1234"_s, pred)); + EXPECT_FALSE(util::all_of("12345"_s, pred)); + EXPECT_FALSE(util::all_of("12345x"_s, pred)); EXPECT_TRUE(util::all_of(cstr(""), pred)); EXPECT_TRUE(util::all_of(cstr("1234"), pred)); @@ -486,10 +488,10 @@ TEST(range, all_of_any_of) { EXPECT_FALSE(util::all_of(cstr("12345x"), pred)); // any - EXPECT_FALSE(util::any_of(std::string(), pred)); - EXPECT_FALSE(util::any_of(std::string("8765"), pred)); - EXPECT_TRUE(util::any_of(std::string("87654"), pred)); - EXPECT_TRUE(util::any_of(std::string("87654x"), pred)); + EXPECT_FALSE(util::any_of(""_s, pred)); + EXPECT_FALSE(util::any_of("8765"_s, pred)); + EXPECT_TRUE(util::any_of("87654"_s, pred)); + EXPECT_TRUE(util::any_of("87654x"_s, pred)); EXPECT_FALSE(util::any_of(cstr(""), pred)); EXPECT_FALSE(util::any_of(cstr("8765"), pred)); diff --git a/tests/unit/test_strprintf.cpp b/tests/unit/test_strprintf.cpp index 93eacb40ee1fb4d1bfa8f8c1e0466c1c4f5a51ce..3bb01dd8f409f2737d2514458e8b74ca44f46970 100644 --- a/tests/unit/test_strprintf.cpp +++ b/tests/unit/test_strprintf.cpp @@ -2,11 +2,13 @@ #include <memory> #include <string> -#include "../gtest.h" #include <util/strprintf.hpp> -using namespace arb::util; +#include "../gtest.h" +#include "common.hpp" +using namespace arb::util; +using namespace testing::string_literals; TEST(strprintf, simple) { char buf[200]; @@ -58,6 +60,6 @@ TEST(strprintf, wrappers) { EXPECT_EQ(std::string(buf), strprintf("sptr %p", sptr)); - EXPECT_EQ(std::string("fish"), strprintf("fi%s", std::string("sh"))); + EXPECT_EQ("fish"_s, strprintf("fi%s", "sh"_s)); } diff --git a/tests/unit/test_uninitialized.cpp b/tests/unit/test_uninitialized.cpp index bb38e3d038ff1c2656ae8442183987029d9d85c2..59683b2e11138fb15a74ee97c14c084953c6f289 100644 --- a/tests/unit/test_uninitialized.cpp +++ b/tests/unit/test_uninitialized.cpp @@ -14,21 +14,21 @@ namespace { count_ops& operator=(const count_ops& n) { ++copy_assign_count; return *this; } count_ops& operator=(count_ops&& n) { ++move_assign_count; return *this; } - static int copy_ctor_count,copy_assign_count; - static int move_ctor_count,move_assign_count; + static int copy_ctor_count, copy_assign_count; + static int move_ctor_count, move_assign_count; static void reset_counts() { - copy_ctor_count=copy_assign_count=0; - move_ctor_count=move_assign_count=0; + copy_ctor_count = copy_assign_count = 0; + move_ctor_count = move_assign_count = 0; } }; - int count_ops::copy_ctor_count=0; - int count_ops::copy_assign_count=0; - int count_ops::move_ctor_count=0; - int count_ops::move_assign_count=0; + int count_ops::copy_ctor_count = 0; + int count_ops::copy_assign_count = 0; + int count_ops::move_ctor_count = 0; + int count_ops::move_assign_count = 0; } -TEST(uninitialized,ctor) { +TEST(uninitialized, ctor) { count_ops::reset_counts(); uninitialized<count_ops> ua; @@ -37,37 +37,37 @@ TEST(uninitialized,ctor) { count_ops b; ua.construct(b); - EXPECT_EQ(1,count_ops::copy_ctor_count); - EXPECT_EQ(0,count_ops::copy_assign_count); - EXPECT_EQ(1,count_ops::move_ctor_count); - EXPECT_EQ(0,count_ops::move_assign_count); + EXPECT_EQ(1, count_ops::copy_ctor_count); + EXPECT_EQ(0, count_ops::copy_assign_count); + EXPECT_EQ(1, count_ops::move_ctor_count); + EXPECT_EQ(0, count_ops::move_assign_count); - ua.ref()=count_ops{}; - ua.ref()=b; + ua.ref() = count_ops{}; + ua.ref() = b; - EXPECT_EQ(1,count_ops::copy_ctor_count); - EXPECT_EQ(1,count_ops::copy_assign_count); - EXPECT_EQ(1,count_ops::move_ctor_count); - EXPECT_EQ(1,count_ops::move_assign_count); + EXPECT_EQ(1, count_ops::copy_ctor_count); + EXPECT_EQ(1, count_ops::copy_assign_count); + EXPECT_EQ(1, count_ops::move_ctor_count); + EXPECT_EQ(1, count_ops::move_assign_count); } -TEST(uninitialized,ctor_nocopy) { +TEST(uninitialized, ctor_nocopy) { using nocopy = testing::nocopy<int>; nocopy::reset_counts(); uninitialized<nocopy> ua; ua.construct(nocopy{}); - EXPECT_EQ(1,nocopy::move_ctor_count); - EXPECT_EQ(0,nocopy::move_assign_count); + EXPECT_EQ(1, nocopy::move_ctor_count); + EXPECT_EQ(0, nocopy::move_assign_count); - ua.ref()=nocopy{}; + ua.ref() = nocopy{}; - EXPECT_EQ(1,nocopy::move_ctor_count); - EXPECT_EQ(1,nocopy::move_assign_count); + EXPECT_EQ(1, nocopy::move_ctor_count); + EXPECT_EQ(1, nocopy::move_assign_count); } -TEST(uninitialized,ctor_nomove) { +TEST(uninitialized, ctor_nomove) { using nomove = testing::nomove<int>; nomove::reset_counts(); @@ -80,91 +80,37 @@ TEST(uninitialized,ctor_nomove) { const nomove c; ua.construct(c); // check against const lvalue - EXPECT_EQ(3,nomove::copy_ctor_count); - EXPECT_EQ(0,nomove::copy_assign_count); + EXPECT_EQ(3, nomove::copy_ctor_count); + EXPECT_EQ(0, nomove::copy_assign_count); nomove a; - ua.ref()=a; + ua.ref() = a; - EXPECT_EQ(3,nomove::copy_ctor_count); - EXPECT_EQ(1,nomove::copy_assign_count); + EXPECT_EQ(3, nomove::copy_ctor_count); + EXPECT_EQ(1, nomove::copy_assign_count); } -TEST(uninitialized,void) { - uninitialized<void> a,b; - a=b; +TEST(uninitialized, void) { + uninitialized<void> a, b; + a = b; - EXPECT_EQ(typeid(a.ref()),typeid(void)); + EXPECT_EQ(typeid(a.ref()), typeid(void)); } -TEST(uninitialized,ref) { - uninitialized<int&> x,y; +TEST(uninitialized, ref) { + uninitialized<int&> x, y; int a; x.construct(a); - y=x; + y = x; - x.ref()=2; - EXPECT_EQ(2,a); + x.ref() = 2; + EXPECT_EQ(2, a); - y.ref()=3; - EXPECT_EQ(3,a); - EXPECT_EQ(3,x.cref()); + y.ref() = 3; + EXPECT_EQ(3, a); + EXPECT_EQ(3, x.cref()); - EXPECT_EQ(&a,x.ptr()); - EXPECT_EQ((const int *)&a,x.cptr()); -} - -namespace { - struct apply_tester { - mutable int op_count=0; - mutable int const_op_count=0; - - int operator()(const int& a) const { ++const_op_count; return a+1; } - int operator()(int& a) const { ++op_count; return ++a; } - }; -} - -TEST(uninitialized,apply) { - uninitialized<int> ua; - ua.construct(10); - - apply_tester A; - int r=ua.apply(A); - EXPECT_EQ(11,ua.cref()); - EXPECT_EQ(11,r); - - uninitialized<int&> ub; - ub.construct(ua.ref()); - - r=ub.apply(A); - EXPECT_EQ(12,ua.cref()); - EXPECT_EQ(12,r); - - uninitialized<const int&> uc; - uc.construct(ua.ref()); - - r=uc.apply(A); - EXPECT_EQ(12,ua.cref()); - EXPECT_EQ(13,r); - - const uninitialized<int> ud(ua); - - r=ud.apply(A); - - EXPECT_EQ(12,ua.cref()); - EXPECT_EQ(12,ud.cref()); - EXPECT_EQ(13,r); - - EXPECT_EQ(2,A.op_count); - EXPECT_EQ(2,A.const_op_count); -} - -TEST(uninitialized,void_apply) { - uninitialized<void> uv; - - auto f=[]() { return 11; }; - EXPECT_EQ(11,uv.apply(f)); - - EXPECT_EQ(12.5,uv.apply([]() { return 12.5; })); + EXPECT_EQ(&a, x.ptr()); + EXPECT_EQ((const int *)&a, x.cptr()); } diff --git a/tests/unit/test_unique_any.cpp b/tests/unit/test_unique_any.cpp index 8fc88c1e9f453a3fb6f973a848e10ecfa25e0fed..0104619a73ed623cb8609ca7b98947c30cbc0cb7 100644 --- a/tests/unit/test_unique_any.cpp +++ b/tests/unit/test_unique_any.cpp @@ -1,13 +1,14 @@ -#include "../gtest.h" -#include "common.hpp" - #include <iostream> #include <util/rangeutil.hpp> #include <util/span.hpp> #include <util/unique_any.hpp> +#include "../gtest.h" +#include "common.hpp" + using namespace arb; +using namespace testing::string_literals; TEST(unique_any, copy_construction) { using util::unique_any; @@ -24,7 +25,6 @@ TEST(unique_any, copy_construction) { } namespace { - struct moveable { moveable() = default; @@ -39,7 +39,6 @@ namespace { int moves=0; int copies=0; }; - } TEST(unique_any, move_construction) { diff --git a/tests/validation/trace_analysis.cpp b/tests/validation/trace_analysis.cpp index 28d9a47055e714319d7fcc54979d58b3d3293697..685699835a851e15c668cccb4ef7f3a695f1fe90 100644 --- a/tests/validation/trace_analysis.cpp +++ b/tests/validation/trace_analysis.cpp @@ -119,7 +119,7 @@ util::optional<trace_peak> peak_delta(const trace_data<double>& a, const trace_d auto p = local_maxima(a); auto q = local_maxima(b); - if (p.size()!=q.size() || p.empty()) return util::nothing; + if (p.size()!=q.size() || p.empty()) return util::nullopt; auto max_delta = p[0]-q[0];