Program Listing for File recycling.hpp¶
↰ Return to documentation for file (fwdpp/simfunctions/recycling.hpp)
#ifndef FWDPP_RECYCLING
#define FWDPP_RECYCLING
#include <queue>
#include <stdexcept>
#include <type_traits>
#include <fwdpp/util/named_type.hpp>
namespace fwdpp
{
namespace tags
{
struct mutation_recycling
{
};
struct haploid_genome_recycling
{
};
} // namespace tags
using flagged_mutation_queue
= strong_types::named_type<std::queue<std::size_t>, tags::mutation_recycling>;
using flagged_haploid_genome_queue
= strong_types::named_type<std::queue<std::size_t>,
tags::haploid_genome_recycling>;
inline flagged_mutation_queue
empty_mutation_queue()
{
return flagged_mutation_queue(flagged_mutation_queue::value_type());
}
inline flagged_haploid_genome_queue
empty_haploid_genome_queue()
{
return flagged_haploid_genome_queue(flagged_haploid_genome_queue::value_type());
}
template <typename mcount_vec>
inline flagged_mutation_queue
make_mut_queue(const mcount_vec &mcounts)
{
flagged_mutation_queue::value_type rv;
const auto msize = mcounts.size();
for (typename mcount_vec::size_type i = 0; i < msize; ++i)
{
if (!mcounts[i])
rv.push(i);
}
return flagged_mutation_queue(std::move(rv));
}
template <typename gvec_t>
inline flagged_haploid_genome_queue
make_haploid_genome_queue(const gvec_t &haploid_genomes)
{
flagged_haploid_genome_queue::value_type rv;
const auto gsize = haploid_genomes.size();
for (typename gvec_t::size_type i = 0; i < gsize; ++i)
{
if (!haploid_genomes[i].n)
rv.push(i);
}
return flagged_haploid_genome_queue(std::move(rv));
}
template <typename GenomeContainerType>
inline std::size_t
recycle_haploid_genome(
GenomeContainerType &haploid_genomes,
flagged_haploid_genome_queue &haploid_genome_recycling_bin,
typename GenomeContainerType::value_type::mutation_container &neutral,
typename GenomeContainerType::value_type::mutation_container &selected)
{
// Try to recycle
auto &ref = haploid_genome_recycling_bin.get();
if (!ref.empty())
{
auto idx = ref.front();
ref.pop();
#ifndef NDEBUG
if (haploid_genomes[idx].n)
{
throw std::runtime_error(
"FWDPP DEBUG: attempting to recycle an extant "
"haploid_genome");
}
#endif
haploid_genomes[idx].mutations.swap(neutral);
haploid_genomes[idx].smutations.swap(selected);
return idx;
}
haploid_genomes.emplace_back(0u, std::move(neutral), std::move(selected));
return (haploid_genomes.size() - 1);
}
template <typename MutationContainerType, class... Args>
inline std::size_t
recycle_mutation_helper(flagged_mutation_queue &mutation_recycling_bin,
MutationContainerType &mutations, Args &&... args)
{
auto &ref = mutation_recycling_bin.get();
if (!ref.empty())
{
auto rv = ref.front();
ref.pop();
mutations[rv] = typename MutationContainerType::value_type(
std::forward<Args>(args)...);
return rv;
}
mutations.emplace_back(std::forward<Args>(args)...);
return mutations.size() - 1;
}
} // namespace fwdpp
#endif