diff --git a/src/aligner.cpp b/src/aligner.cpp index d0b07f44c8..a1e0d15b33 100644 --- a/src/aligner.cpp +++ b/src/aligner.cpp @@ -2437,14 +2437,12 @@ int8_t* AlignerClient::parse_matrix(istream& matrix_stream) { crash_unless(matrix != nullptr); for (size_t i = 0; i < 16; i++) { if (!matrix_stream.good()) { - std::cerr << "error: vg Aligner::parse_matrix requires a 4x4 whitespace separated integer matrix\n"; - throw ""; + throw std::domain_error("error: vg Aligner::parse_matrix requires a 4x4 whitespace separated integer matrix"); } int score; matrix_stream >> score; if (score > 127 || score < -127) { - std::cerr << "error: vg Aligner::parse_matrix requires values in the range [-127,127]\n"; - throw ""; + throw std::domain_error("error: vg Aligner::parse_matrix requires values in the range [-127,127]"); } matrix[i] = score; } diff --git a/src/banded_global_aligner.cpp b/src/banded_global_aligner.cpp index e3e4b4dbd7..b4f3b5a1b5 100644 --- a/src/banded_global_aligner.cpp +++ b/src/banded_global_aligner.cpp @@ -2793,7 +2793,7 @@ BandedGlobalAligner::AltTracebackStack::Deflection::Deflection(const in } template -BandedGlobalAligner::AltTracebackStack::Deflection::~Deflection() { +BandedGlobalAligner::AltTracebackStack::Deflection::~Deflection() noexcept { // nothing to do } diff --git a/src/banded_global_aligner.hpp b/src/banded_global_aligner.hpp index 5a842f92d9..cefaac6ccd 100644 --- a/src/banded_global_aligner.hpp +++ b/src/banded_global_aligner.hpp @@ -314,7 +314,7 @@ namespace vg { public: Deflection(const int64_t from_node_id, const int64_t row_idx, const int64_t col_idx, const int64_t to_node_id, const matrix_t to_matrix); - ~Deflection(); + ~Deflection() noexcept; /// Node ID where deflection occurs const int64_t from_node_id; diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 334bef289f..a25f730827 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -156,7 +156,11 @@ BenchmarkResult run_benchmark(const string& name, size_t iterations, const funct test_samples.push_back(chrono::duration_cast(test_stop - test_start).count()); control_samples.push_back(chrono::duration_cast(control_stop - control_start).count()); } - + + if (iterations == 0) { + return to_return; + } + // Calculate the moments with magic numeric algorithms // See diff --git a/src/cluster.cpp b/src/cluster.cpp index 5b7b1ee8f2..a12e0e398c 100644 --- a/src/cluster.cpp +++ b/src/cluster.cpp @@ -2672,9 +2672,9 @@ int64_t TipAnchoredMaxDistance::operator()(const pos_t& pos_1, const pos_t& pos_ } TargetValueSearch::TargetValueSearch(const HandleGraph& handle_graph, - DistanceHeuristic* upper_bound_heuristic, - DistanceHeuristic* lower_bound_heuristic) : - handle_graph(handle_graph), upper_bound_heuristic(upper_bound_heuristic), lower_bound_heuristic(lower_bound_heuristic) { + std::unique_ptr upper_bound_heuristic, + std::unique_ptr lower_bound_heuristic) : + handle_graph(handle_graph), upper_bound_heuristic(std::move(upper_bound_heuristic)), lower_bound_heuristic(std::move(lower_bound_heuristic)) { // nothing else to do } @@ -3164,8 +3164,10 @@ int64_t TargetValueSearch::tv_path_length(const pos_t& pos_1, const pos_t& pos_2 } TVSClusterer::TVSClusterer(const HandleGraph* handle_graph, SnarlDistanceIndex* distance_index) : - tvs(*handle_graph, new TipAnchoredMaxDistance(*distance_index), new SnarlMinDistance(*distance_index)) { - + tvs(*handle_graph, + std::make_unique(*distance_index), + std::make_unique(*distance_index)) { + // nothing else to do } @@ -3819,7 +3821,7 @@ vector > mem_node_start_positions(const HandleGrap } } } - next = todo; + next = std::move(todo); } // ensure positions are sorted by remainder std::sort(positions.begin(), positions.end(), diff --git a/src/cluster.hpp b/src/cluster.hpp index df997cc51c..39a2bb6e7a 100644 --- a/src/cluster.hpp +++ b/src/cluster.hpp @@ -619,8 +619,8 @@ class TargetValueSearch { public: TargetValueSearch() = delete; TargetValueSearch(const HandleGraph& handle_graph, - DistanceHeuristic* upper_bound_heuristic, - DistanceHeuristic* lower_bound_heuristic); + std::unique_ptr upper_bound_heuristic, + std::unique_ptr lower_bound_heuristic); ~TargetValueSearch() = default; /// Does a path exist from pos_1 to pos_2 with length within the tolerance from the target value? diff --git a/src/dozeu_interface.hpp b/src/dozeu_interface.hpp index 11203ed802..f753c66f6d 100644 --- a/src/dozeu_interface.hpp +++ b/src/dozeu_interface.hpp @@ -291,9 +291,9 @@ class XdropAligner : public DozeuInterface { /// Copy assignment XdropAligner& operator=(const XdropAligner& other); /// Move constructor - XdropAligner(XdropAligner&& other); + XdropAligner(XdropAligner&& other) noexcept; /// Move assignment - XdropAligner& operator=(XdropAligner&& other); + XdropAligner& operator=(XdropAligner&& other) noexcept; }; /* @@ -337,9 +337,9 @@ class QualAdjXdropAligner : public DozeuInterface { /// Copy assignment QualAdjXdropAligner& operator=(const QualAdjXdropAligner& other); /// Move constructor - QualAdjXdropAligner(QualAdjXdropAligner&& other); + QualAdjXdropAligner(QualAdjXdropAligner&& other) noexcept; /// Move assignment - QualAdjXdropAligner& operator=(QualAdjXdropAligner&& other); + QualAdjXdropAligner& operator=(QualAdjXdropAligner&& other) noexcept; }; } // end of namespace vg diff --git a/src/explainer.cpp b/src/explainer.cpp index d89eb6ac0f..9eb9103b32 100644 --- a/src/explainer.cpp +++ b/src/explainer.cpp @@ -297,7 +297,11 @@ DiagramExplainer::~DiagramExplainer() { if (!explaining()) { return; } - write_connected_components(); + try { + write_connected_components(); + } catch (...) { + // Cannot propagate exceptions from destructor + } } void DiagramExplainer::add_globals(const annotation_t& annotations) { diff --git a/src/gbwt_extender.cpp b/src/gbwt_extender.cpp index 5061b76436..7eabef7bb3 100644 --- a/src/gbwt_extender.cpp +++ b/src/gbwt_extender.cpp @@ -1460,6 +1460,9 @@ struct WFANode { // Points on the wavefronts are indexed by score, diagonal. std::array, 3> wavefronts; + WFANode(WFANode&&) noexcept = default; + WFANode& operator=(WFANode&&) noexcept = default; + WFANode(const gbwtgraph::CachedGBWTGraph& graph, const gbwt::SearchState& state, pos_t target, std::uint32_t parent) : parent(parent), target_offset(std::numeric_limits::max()), dead_end(false) { @@ -1625,7 +1628,7 @@ class WFATree { gbwt::SearchState state = this->graph.get_state(handle); WFANode root(this->graph, state, this->to, 0); root.update(WFANode::MATCHES, 0, 0, 0, offset(this->from) + 1); - this->nodes.push_back(root); + this->nodes.push_back(std::move(root)); // Determine score bound based on the error model and sequence length. std::int32_t max_mismatches = error_model.mismatches.evaluate(sequence.length()); diff --git a/src/hash_map.hpp b/src/hash_map.hpp index f4299c9983..a1359246f4 100644 --- a/src/hash_map.hpp +++ b/src/hash_map.hpp @@ -133,11 +133,15 @@ class hash_map : public google::dense_hash_map> class hash_map : public spp::sparse_hash_map> #endif { -#ifdef USE_DENSE_HASH public: + hash_map(hash_map&&) noexcept = default; + hash_map& operator=(hash_map&&) noexcept = default; +#ifdef USE_DENSE_HASH hash_map() { this->set_empty_key(-1); } +#else + hash_map() = default; #endif }; @@ -163,11 +167,15 @@ class pair_hash_map : public google::dense_hash_map> class pair_hash_map : public spp::sparse_hash_map> #endif { -#ifdef USE_DENSE_HASH public: + pair_hash_map(pair_hash_map&&) noexcept = default; + pair_hash_map& operator=(pair_hash_map&&) noexcept = default; +#ifdef USE_DENSE_HASH pair_hash_map() { this->set_empty_key(K(-1, -1)); } +#else + pair_hash_map() = default; #endif }; @@ -196,11 +204,15 @@ class hash_set : public google::dense_hash_set> class hash_set : public spp::sparse_hash_set> #endif { -#ifdef USE_DENSE_HASH public: + hash_set(hash_set&&) noexcept = default; + hash_set& operator=(hash_set&&) noexcept = default; +#ifdef USE_DENSE_HASH hash_set() { this->set_empty_key(-1); } +#else + hash_set() = default; #endif }; @@ -226,11 +238,15 @@ class pair_hash_set : public google::dense_hash_set> class pair_hash_set : public spp::sparse_hash_set> #endif { -#ifdef USE_DENSE_HASH public: + pair_hash_set(pair_hash_set&&) noexcept = default; + pair_hash_set& operator=(pair_hash_set&&) noexcept = default; +#ifdef USE_DENSE_HASH pair_hash_set() { this->set_empty_key(K(-1, -1)); } +#else + pair_hash_set() = default; #endif }; diff --git a/src/hts_alignment_emitter.cpp b/src/hts_alignment_emitter.cpp index 58a4e6859b..8b95dfa335 100644 --- a/src/hts_alignment_emitter.cpp +++ b/src/hts_alignment_emitter.cpp @@ -518,7 +518,7 @@ HTSWriter::~HTSWriter() { for (size_t thread_number = 0; thread_number < sam_files.size(); thread_number++) { // For each thread, find its samFile* - auto& sam_file = sam_files.at(thread_number); + auto& sam_file = sam_files[thread_number]; if (sam_file != nullptr) { // Close out all the open samFile*s and flush their data before the diff --git a/src/index_registry.cpp b/src/index_registry.cpp index 95f6127da6..5f2b67567c 100644 --- a/src/index_registry.cpp +++ b/src/index_registry.cpp @@ -4832,7 +4832,7 @@ IndexRegistry::~IndexRegistry() { } } -IndexRegistry::IndexRegistry(IndexRegistry&& other) : +IndexRegistry::IndexRegistry(IndexRegistry&& other) noexcept : index_registry(std::move(other.index_registry)), recipe_registry(std::move(other.recipe_registry)), registered_suffixes(std::move(other.registered_suffixes)), @@ -4844,7 +4844,7 @@ IndexRegistry::IndexRegistry(IndexRegistry&& other) : other.work_dir.clear(); } -IndexRegistry& IndexRegistry::operator=(IndexRegistry&& other) { +IndexRegistry& IndexRegistry::operator=(IndexRegistry&& other) noexcept { index_registry = std::move(other.index_registry); recipe_registry = std::move(other.recipe_registry); registered_suffixes = std::move(other.registered_suffixes); diff --git a/src/index_registry.hpp b/src/index_registry.hpp index d6545bf9f4..d5cb593364 100644 --- a/src/index_registry.hpp +++ b/src/index_registry.hpp @@ -269,8 +269,8 @@ class IndexRegistry { IndexRegistry& operator=(const IndexRegistry& other) = delete; // And we need to be moved carefully - IndexRegistry(IndexRegistry&& other); - IndexRegistry& operator=(IndexRegistry&& other); + IndexRegistry(IndexRegistry&& other) noexcept; + IndexRegistry& operator=(IndexRegistry&& other) noexcept; /// Prefix for all saved outputs diff --git a/src/mem.hpp b/src/mem.hpp index a3aa06e295..ad881b1f9a 100644 --- a/src/mem.hpp +++ b/src/mem.hpp @@ -58,9 +58,9 @@ class MaximalExactMatch { MaximalExactMatch(void) = default; // Copy constructor MaximalExactMatch(const MaximalExactMatch&) = default; // Copy constructor - MaximalExactMatch(MaximalExactMatch&&) = default; // Move constructor + MaximalExactMatch(MaximalExactMatch&&) noexcept = default; // Move constructor MaximalExactMatch& operator=(const MaximalExactMatch&) & = default; // Copy assignment operator - MaximalExactMatch& operator=(MaximalExactMatch&&) & = default; // Move assignment operator + MaximalExactMatch& operator=(MaximalExactMatch&&) & noexcept = default; // Move assignment operator //virtual ~MaximalExactMatch() { } // Destructor }; diff --git a/src/minimizer_mapper.hpp b/src/minimizer_mapper.hpp index 41a376069e..d9fee295ad 100644 --- a/src/minimizer_mapper.hpp +++ b/src/minimizer_mapper.hpp @@ -1590,8 +1590,8 @@ void MinimizerMapper::process_until_threshold_e(size_t items, const function> diff --git a/src/multipath_alignment.hpp b/src/multipath_alignment.hpp index 319de8ce52..445b5fadd3 100644 --- a/src/multipath_alignment.hpp +++ b/src/multipath_alignment.hpp @@ -88,10 +88,10 @@ namespace vg { public: multipath_alignment_t(); multipath_alignment_t(const multipath_alignment_t& other); - multipath_alignment_t(multipath_alignment_t&& other); + multipath_alignment_t(multipath_alignment_t&& other) noexcept; ~multipath_alignment_t(); multipath_alignment_t& operator=(const multipath_alignment_t& other); - multipath_alignment_t& operator=(multipath_alignment_t&& other); + multipath_alignment_t& operator=(multipath_alignment_t&& other) noexcept; inline const string& sequence() const; inline string* mutable_sequence(); inline void set_sequence(const string& s); diff --git a/src/packer.cpp b/src/packer.cpp index ee5183cac2..d7a1f22a6f 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -679,6 +679,7 @@ size_t Packer::node_quality_vector_size(void) const { } pair Packer::coverage_bin_offset(size_t i) const { + if (cov_bin_size == 0) return {0, i}; size_t bin = min((size_t)(i / cov_bin_size), (size_t)(coverage_dynamic.size() - 1)); // last bin can have different size so we don't use mod size_t offset = i - bin * cov_bin_size; @@ -693,6 +694,7 @@ pair Packer::edge_coverage_bin_offset(size_t i) const { } pair Packer::node_quality_bin_offset(size_t i) const { + if (node_qual_bin_size == 0) return {0, i}; size_t bin = min((size_t)(i / node_qual_bin_size), (size_t)(node_quality_dynamic.size() - 1)); // last bin can have different size so we don't use mod size_t offset = i - bin * node_qual_bin_size; diff --git a/src/qual_adj_xdrop_aligner.cpp b/src/qual_adj_xdrop_aligner.cpp index 05ee8aacbb..9edbdc8610 100644 --- a/src/qual_adj_xdrop_aligner.cpp +++ b/src/qual_adj_xdrop_aligner.cpp @@ -53,12 +53,12 @@ QualAdjXdropAligner& QualAdjXdropAligner::operator=(const QualAdjXdropAligner& o return *this; } -QualAdjXdropAligner::QualAdjXdropAligner(QualAdjXdropAligner&& other) +QualAdjXdropAligner::QualAdjXdropAligner(QualAdjXdropAligner&& other) noexcept { *this = other; } -QualAdjXdropAligner& QualAdjXdropAligner::operator=(QualAdjXdropAligner&& other) +QualAdjXdropAligner& QualAdjXdropAligner::operator=(QualAdjXdropAligner&& other) noexcept { if (this != &other) { if (dz) { diff --git a/src/recombinator.hpp b/src/recombinator.hpp index 783f1faf12..0f4a13d35c 100644 --- a/src/recombinator.hpp +++ b/src/recombinator.hpp @@ -154,6 +154,10 @@ class Haplotypes { /// Sequence `i` contains kmer `j` if and only if `kmers_present[i * kmers.size() + j] == 1`. sdsl::bit_vector kmers_present; + Subchain() = default; + Subchain(Subchain&&) noexcept = default; + Subchain& operator=(Subchain&&) noexcept = default; + /// Returns the start node as a GBWTGraph handle. handle_t start_handle() const { return gbwtgraph::GBWTGraph::node_to_handle(this->start); } diff --git a/src/small_bitset.hpp b/src/small_bitset.hpp index 11e3fd691d..6b6552f119 100644 --- a/src/small_bitset.hpp +++ b/src/small_bitset.hpp @@ -34,7 +34,7 @@ class SmallBitset { this->copy(another); } - SmallBitset(SmallBitset&& another) { + SmallBitset(SmallBitset&& another) noexcept { this->move(another); } @@ -46,7 +46,7 @@ class SmallBitset { return *this; } - SmallBitset& operator=(SmallBitset&& another) { + SmallBitset& operator=(SmallBitset&& another) noexcept { if (&another != this) { this->clear(); this->move(another); diff --git a/src/snarl_seed_clusterer.hpp b/src/snarl_seed_clusterer.hpp index 1960d8b2db..460737e0b2 100644 --- a/src/snarl_seed_clusterer.hpp +++ b/src/snarl_seed_clusterer.hpp @@ -84,14 +84,14 @@ class SnarlDistanceIndexClusterer { } //Move constructor - Seed (Seed&& other) : + Seed (Seed&& other) noexcept : pos(std::move(other.pos)), source(std::move(other.source)), zipcode(std::move(other.zipcode)), paths(std::move(other.paths)){} //Move assignment operator - Seed& operator=(Seed&& other) { + Seed& operator=(Seed&& other) noexcept { pos = std::move(other.pos); source = std::move(other.source); zipcode = std::move(other.zipcode); @@ -277,9 +277,10 @@ class SnarlDistanceIndexClusterer { bool is_trivial_chain = false; bool is_looping_chain = false; - - + // Explicit noexcept move operations + SnarlTreeNodeProblem(SnarlTreeNodeProblem&&) noexcept = default; + SnarlTreeNodeProblem& operator=(SnarlTreeNodeProblem&&) noexcept = default; //Constructor //read_count is the number of reads in a fragment (2 for paired end) diff --git a/src/subcommand/annotate_main.cpp b/src/subcommand/annotate_main.cpp index c4df6df38a..c431770fd4 100644 --- a/src/subcommand/annotate_main.cpp +++ b/src/subcommand/annotate_main.cpp @@ -415,7 +415,7 @@ int main_annotate(int argc, char** argv) { } // define a function that converts to GGFF - RegionExpander region_expander(&(*xg_index), &(*snarl_manager)); + RegionExpander region_expander(xg_index, snarl_manager.get()); function output_ggff_record = [&](const GFFRecord& record) { auto subgraph = region_expander.expanded_subgraph(record); diff --git a/src/subcommand/dotplot_main.cpp b/src/subcommand/dotplot_main.cpp index 89dffec9b4..8e769a6bf5 100644 --- a/src/subcommand/dotplot_main.cpp +++ b/src/subcommand/dotplot_main.cpp @@ -94,7 +94,7 @@ int main_dotplot(int argc, char** argv) { vg::id_t id = xindex->get_id(h); for (size_t i = 0; i < xindex->get_length(xindex->get_handle(id)); ++i) { pos_t p = make_pos_t(id, false, i); - map > > offsets = algorithms::offsets_in_paths(&(*xindex), p); + map > > offsets = algorithms::offsets_in_paths(xindex, p); // cross the offsets in output for (auto& o : offsets) { auto& name1 = o.first; diff --git a/src/subcommand/find_main.cpp b/src/subcommand/find_main.cpp index d35e874cbf..2d5976b686 100644 --- a/src/subcommand/find_main.cpp +++ b/src/subcommand/find_main.cpp @@ -608,7 +608,7 @@ int main_find(int argc, char** argv) { if (node_ids.size() != 2) { logger.error() << "exactly 2 nodes (-n) required with -D" << endl; } - cout << vg::algorithms::min_approx_path_distance(dynamic_cast(&*xindex), + cout << vg::algorithms::min_approx_path_distance(xindex, make_pos_t(node_ids[0], false, 0), make_pos_t(node_ids[1], false, 0), 1000) << endl; return 0; } diff --git a/src/subcommand/msga_main.cpp b/src/subcommand/msga_main.cpp index c999eed081..1c744cf0f0 100644 --- a/src/subcommand/msga_main.cpp +++ b/src/subcommand/msga_main.cpp @@ -731,7 +731,8 @@ int main_msga(int argc, char** argv) { db_out.close(); } #endif - while (incomplete && iter++ < iter_max) { + while (incomplete && iter < iter_max) { + iter++; stringstream s; s << iter; string iterstr = s.str(); if (debug) { logger.info() << name << ": adding to graph " diff --git a/src/subcommand/options.hpp b/src/subcommand/options.hpp index 0f1d38a3f2..4f142fd5bf 100644 --- a/src/subcommand/options.hpp +++ b/src/subcommand/options.hpp @@ -204,10 +204,10 @@ struct Range : public subcommand::TickChainLink { } /// Move, preserving destination links - Range(Range&& other): start(other.start), end(other.end), step(other.step) { + Range(Range&& other) noexcept: start(other.start), end(other.end), step(other.step) { // Nothing to do } - + /// Copy assignment, preserving destination links Range& operator=(const Range& other) { start = other.start; @@ -215,9 +215,9 @@ struct Range : public subcommand::TickChainLink { step = other.step; return *this; } - + /// Move assignment, preserving destination links - Range& operator=(Range&& other) { + Range& operator=(Range&& other) noexcept { start = other.start; end = other.end; step = other.step; @@ -447,9 +447,9 @@ struct Valuation : public BaseValuation { // Valuations are copyable and assignable. Valuation(const Valuation& other) = default; - Valuation(Valuation&& other) = default; + Valuation(Valuation&& other) noexcept = default; Valuation& operator=(const Valuation& other) = default; - Valuation& operator=(Valuation&& other) = default; + Valuation& operator=(Valuation&& other) noexcept = default; /// Value for the option T value; diff --git a/src/unittest/cluster.cpp b/src/unittest/cluster.cpp index e2c732a10f..dd0baf580d 100644 --- a/src/unittest/cluster.cpp +++ b/src/unittest/cluster.cpp @@ -58,8 +58,8 @@ namespace unittest { SnarlDistanceIndex di; IntegratedSnarlFinder snarl_finder(graph); fill_in_distance_index (&di, &graph, &snarl_finder); - TargetValueSearch tvs(graph, new TipAnchoredMaxDistance(di), - new SnarlMinDistance(di)); + TargetValueSearch tvs(graph, std::make_unique(di), + std::make_unique(di)); SECTION( "Test tvs" ) { @@ -142,8 +142,8 @@ namespace unittest { SnarlDistanceIndex di; IntegratedSnarlFinder snarl_finder(graph); fill_in_distance_index (&di, &graph, &snarl_finder); - TargetValueSearch tvs(graph, new TipAnchoredMaxDistance(di), - new SnarlMinDistance(di)); + TargetValueSearch tvs(graph, std::make_unique(di), + std::make_unique(di)); SECTION( "Test tvs" ) { @@ -202,8 +202,8 @@ namespace unittest { SnarlDistanceIndex di; IntegratedSnarlFinder snarl_finder(graph); fill_in_distance_index (&di, &graph, &snarl_finder); - TargetValueSearch tvs(graph, new TipAnchoredMaxDistance(di), - new SnarlMinDistance(di)); + TargetValueSearch tvs(graph, std::make_unique(di), + std::make_unique(di)); SECTION( "Test tvs" ) { @@ -240,8 +240,8 @@ namespace unittest { SnarlDistanceIndex di; IntegratedSnarlFinder snarl_finder(graph); fill_in_distance_index (&di, &graph, &snarl_finder); - TargetValueSearch tvs(graph, new TipAnchoredMaxDistance(di), - new SnarlMinDistance(di)); + TargetValueSearch tvs(graph, std::make_unique(di), + std::make_unique(di)); vector allSnarls; auto addSnarl = [&] (const Snarl* s) { diff --git a/src/unittest/min_cut_graph.cpp b/src/unittest/min_cut_graph.cpp index 1a2cd1ef75..5f3bd0387c 100644 --- a/src/unittest/min_cut_graph.cpp +++ b/src/unittest/min_cut_graph.cpp @@ -12,7 +12,8 @@ #include "catch.hpp" #include #include "sparse_union_find.hpp" -#include +#include "support/randomness.hpp" +#include #include #include #include @@ -1041,14 +1042,12 @@ namespace vg { TEST_CASE("min-cut-decompomposition works on a 1000 node graph", "[Min-cut-graph][MCG-Test10]") { Graph graph; size_t max_nodes = 1000; + std::mt19937 rng(vg::unittest::test_seed_source()); + std::uniform_int_distribution dist(1, 999); // 1–999, 0 not allowed for(size_t i = 0; i +#include #include "vg/io/json2pb.h" #include "../io/json2graph.hpp" #include @@ -14,6 +15,7 @@ #include "xg.hpp" #include "vg.hpp" #include "catch.hpp" +#include "support/randomness.hpp" namespace vg { namespace unittest { @@ -191,20 +193,23 @@ TEST_CASE("Mapping quality cap cannot be confused by fuzzing with high base qual minimizer_template.occs.first = nullptr; minimizer_template.score = 1; + std::mt19937 rng(vg::unittest::test_seed_source()); for (size_t try_number = 0; try_number < 100000; try_number++) { - + vector minimizers; // They are all going to be explored vector minimizers_explored; - - size_t minimizer_count = rand() % 100 + 5; - + + size_t minimizer_count = std::uniform_int_distribution(5, 104)(rng); + for (size_t i = 0; i < minimizer_count; i++) { // Generate a random and not very realistic agglomeration - size_t core_width = rand() % std::min(sequence.size()/2 - 1, (size_t)32 - 1) + 1; - size_t run_length = rand() % std::min(sequence.size() - core_width, (size_t)32 - core_width); - size_t flank_width = rand() % 10; - size_t core_start = rand() % (sequence.size() - core_width - run_length); + size_t max_core_width = std::min(sequence.size()/2 - 1, (size_t)32 - 1); + size_t core_width = std::uniform_int_distribution(1, max_core_width)(rng); + size_t max_run_length = std::min(sequence.size() - core_width, (size_t)32 - core_width); + size_t run_length = std::uniform_int_distribution(0, max_run_length)(rng); + size_t flank_width = std::uniform_int_distribution(0, 9)(rng); + size_t core_start = std::uniform_int_distribution(0, sequence.size() - core_width - run_length - 1)(rng); string min_seq; for (int i = 0; i < core_width; i++) { diff --git a/src/unittest/snarl_seed_clusterer.cpp b/src/unittest/snarl_seed_clusterer.cpp index fdc843f366..b5842c613b 100644 --- a/src/unittest/snarl_seed_clusterer.cpp +++ b/src/unittest/snarl_seed_clusterer.cpp @@ -1367,7 +1367,7 @@ namespace unittest { for (size_t s : c.seeds) { h.insert(s); } - cluster_sets.push_back(h); + cluster_sets.push_back(std::move(h)); } REQUIRE( clusters.size() == 2); REQUIRE (( (cluster_sets[0].count(0) == 1 && @@ -1952,7 +1952,7 @@ namespace unittest { for (size_t s : c.seeds) { h.insert(s); } - cluster_sets.push_back(h); + cluster_sets.push_back(std::move(h)); } REQUIRE (( (cluster_sets[0].count(0) == 1 && cluster_sets[0].count(1) == 1 && diff --git a/src/unittest/support/randomness.hpp b/src/unittest/support/randomness.hpp index 4bc09f8948..9c2e56fc65 100644 --- a/src/unittest/support/randomness.hpp +++ b/src/unittest/support/randomness.hpp @@ -9,7 +9,6 @@ */ #include -#include namespace vg { namespace unittest { @@ -21,8 +20,8 @@ namespace unittest { * USE INSTEAD OF A NEW std::random_device FOR ALL TESTING PURPOSES! */ inline unsigned int test_seed_source() { - // TODO: make thread safe - return (unsigned int) rand(); + static std::mt19937 rng(std::random_device{}()); + return static_cast(rng()); } } diff --git a/src/utility.hpp b/src/utility.hpp index 53c428fd94..bd93f5d19b 100644 --- a/src/utility.hpp +++ b/src/utility.hpp @@ -288,9 +288,9 @@ struct VectorView { // Behave like a nice value. ~VectorView() = default; VectorView(const VectorView& other) = default; - VectorView(VectorView&& other) = default; + VectorView(VectorView&& other) noexcept = default; VectorView& operator=(const VectorView& other) = default; - VectorView& operator=(VectorView&& other) = default; + VectorView& operator=(VectorView&& other) noexcept = default; /** * Make a VectorView of a whole vector. Provides an implicit conversion. @@ -574,9 +574,9 @@ class IndirectVectorView { IndirectVectorView() = default; ~IndirectVectorView() = default; IndirectVectorView(const IndirectVectorView& other) = default; - IndirectVectorView(IndirectVectorView&& other) = default; + IndirectVectorView(IndirectVectorView&& other) noexcept = default; IndirectVectorView& operator=(const IndirectVectorView& other) = default; - IndirectVectorView& operator=(IndirectVectorView&& other) = default; + IndirectVectorView& operator=(IndirectVectorView&& other) noexcept = default; void push_back(Item& item) { return items.push_back(&item); diff --git a/src/variant_adder.cpp b/src/variant_adder.cpp index d6e70bc423..06433a64ef 100644 --- a/src/variant_adder.cpp +++ b/src/variant_adder.cpp @@ -377,7 +377,7 @@ void VariantAdder::add_variants(vcflib::VariantCallFile* vcf) { } while (have_dangling_ends); } - if (print_updates && (variants_processed++ % 1000 == 0 || true)) { + if (print_updates && variants_processed++ % 1000 == 0) { #pragma omp critical (cerr) cerr << "Variant " << variants_processed << ": " << haplotypes.size() << " haplotypes at " << variant->sequenceName << ":" << variant->position << ": " diff --git a/src/viz.hpp b/src/viz.hpp index 94edb354a4..880059557c 100644 --- a/src/viz.hpp +++ b/src/viz.hpp @@ -22,7 +22,13 @@ using namespace std; class Viz { public: Viz(void) { } - ~Viz(void) { close(); } + ~Viz(void) { + try { + close(); + } catch (...) { + // Cannot propagate exceptions from destructor + } + } Viz(PathHandleGraph* x, vector* p, const vector& n, const string& o, int w, int h, bool c, bool d, bool t); void init(PathHandleGraph* x, vector* p, const vector& n, const string& o, int w, int h, bool c, bool d, bool t); void draw(void); diff --git a/src/xdrop_aligner.cpp b/src/xdrop_aligner.cpp index c98bc15a18..9ff1dc513c 100644 --- a/src/xdrop_aligner.cpp +++ b/src/xdrop_aligner.cpp @@ -50,12 +50,12 @@ XdropAligner& XdropAligner::operator=(const XdropAligner& other) return *this; } -XdropAligner::XdropAligner(XdropAligner&& other) +XdropAligner::XdropAligner(XdropAligner&& other) noexcept { *this = other; } -XdropAligner& XdropAligner::operator=(XdropAligner&& other) +XdropAligner& XdropAligner::operator=(XdropAligner&& other) noexcept { if (this != &other) { if (dz) { diff --git a/src/zip_code_tree.hpp b/src/zip_code_tree.hpp index 42af074ab3..0899a1a3bf 100644 --- a/src/zip_code_tree.hpp +++ b/src/zip_code_tree.hpp @@ -331,7 +331,7 @@ class ZipCodeTree { /// Compare to other instances. TODO: Use default when we get C++20. inline bool operator==(const seed_result_t& other) const { - return distance == other.distance && oriented_seed_t::operator==((oriented_seed_t)other); + return distance == other.distance && oriented_seed_t::operator==(static_cast(other)); } /// Compare to other instances. TODO: Use default when we get C++20. diff --git a/src/zstdutil.cpp b/src/zstdutil.cpp index d732c22b3e..4dee7e6e8a 100644 --- a/src/zstdutil.cpp +++ b/src/zstdutil.cpp @@ -20,7 +20,11 @@ zstd_compress_buf::zstd_compress_buf(std::streambuf* inner, int compression_leve } zstd_compress_buf::~zstd_compress_buf() { - this->sync(); + try { + this->sync(); + } catch (...) { + // Cannot propagate exceptions from destructor + } ZSTD_freeCCtx(this->context); this->context = nullptr; }