Program Listing for File GarbledOutputIterator.hpp¶
↰ Return to documentation for file (include/sgpl/utility/GarbledOutputIterator.hpp)
#pragma once
#ifndef SGPL_UTILITY_GARBLEDOUTPUTITERATOR_HPP_INCLUDE
#define SGPL_UTILITY_GARBLEDOUTPUTITERATOR_HPP_INCLUDE
#include <iterator>
#include <type_traits>
#include "../../../third-party/conduit/include/uit_emp/math/Random.hpp"
#include "ThreadLocalRandom.hpp"
namespace sgpl {
// if emp::Random constructor available, inject items so constructed as garble
// otherwise, inject default-constructed items
template<typename OutputIterator>
class GarbledOutputIterator
: protected OutputIterator {
using parent_t = OutputIterator;
using container_value_type = typename parent_t::container_type::value_type;
int remaining_garble{};
public:
GarbledOutputIterator(
const OutputIterator& out
) : parent_t(out)
{}
void AddGarble(int amount) {
remaining_garble = std::max(
remaining_garble + amount, 0
);
}
using container_type = typename parent_t::container_type;
using value_type = typename parent_t::value_type;
using pointer = typename parent_t::pointer;
using reference = typename parent_t::reference;
using iterator_category = std::output_iterator_tag;
using difference_type = typename parent_t::difference_type;
GarbledOutputIterator& operator*() { return *this; }
GarbledOutputIterator& operator->() { return *this; }
GarbledOutputIterator& operator++() { return *this; }
GarbledOutputIterator& operator++(int) { return *this; }
GarbledOutputIterator& operator=( const container_value_type& value ) {
if (remaining_garble) {
--remaining_garble;
parent_t::operator=( [](){
using cov_t = container_value_type;
// prefer random constructor, fallback to default constructor
if constexpr ( std::is_constructible_v<cov_t, uit_emp::Random&> ) {
return cov_t( sgpl::tlrand.Get() );
} else return cov_t{};
}() );
} else parent_t::operator=( value );
return *this;
}
};
} // namespace sgpl
#endif // #ifndef SGPL_UTILITY_GARBLEDOUTPUTITERATOR_HPP_INCLUDE