20template<
class Iterator,
class Mask,
class Type>
21bool found(Iterator start, Iterator end, Mask mask, Type candidate) {
22 if constexpr(std::is_same<Mask, bool>::value) {
23 return (std::find(start, end, candidate) != end);
25 for (; start != end; ++start, ++mask) {
26 if (!*mask && candidate == *start) {
34template<class Iterator, class Mask, class Type = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
35std::set<Type> create_unique_set(Iterator start, Iterator end, Mask mask) {
36 if constexpr(std::is_same<Mask, bool>::value) {
37 return std::set<Type>(start, end);
39 std::set<Type> output;
40 for (; start != end; ++start, ++mask) {
42 output.insert(*start);
49template<class Iterator, class Mask, class Type = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
50bool check_for_nan(Iterator start, Iterator end, Mask mask) {
51 if constexpr(std::is_same<Mask, bool>::value) {
52 for (
auto x = start; x != end; ++x) {
59 for (
auto x = start; x != end; ++x, ++sIt) {
60 if (!*sIt && std::isnan(*x)) {
88template<class Iterator, class Mask, class Type_ = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
90 static_assert(std::numeric_limits<Type_>::is_integer);
93 if constexpr(std::numeric_limits<Type_>::is_signed) {
94 auto candidate = std::numeric_limits<Type_>::min();
95 if (!found(start, end, mask, candidate)) {
96 return std::make_pair(
true, candidate);
101 auto candidate = std::numeric_limits<Type_>::max();
102 if (!found(start, end, mask, candidate)) {
103 return std::make_pair(
true, candidate);
107 if (!found(start, end, mask, 0)) {
108 return std::make_pair(
true, 0);
112 auto uniq_sort = create_unique_set(start, end, mask);
113 Type_ last = std::numeric_limits<Type_>::min();
114 for (
auto x : uniq_sort) {
116 return std::make_pair(
true, last + 1);
121 return std::make_pair(
false, 0);
135template<class Iterator, class Type_ = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
156template<class Iterator, class Mask, class Type_ = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
158 if constexpr(std::numeric_limits<Type_>::is_iec559) {
160 if (!check_for_nan(start, end, mask)) {
161 return std::make_pair(
true, std::numeric_limits<Type_>::quiet_NaN());
166 auto inf = std::numeric_limits<Type_>::infinity();
167 if (!found(start, end, mask, inf)) {
168 return std::make_pair(
true, inf);
172 if (!found(start, end, mask, ninf)) {
173 return std::make_pair(
true, ninf);
179 auto candidate = std::numeric_limits<Type_>::lowest();
180 if (!found(start, end, mask, candidate)) {
181 return std::make_pair(
true, candidate);
186 auto candidate = std::numeric_limits<Type_>::max();
187 if (!found(start, end, mask, candidate)) {
188 return std::make_pair(
true, candidate);
192 if (!found(start, end, mask, 0)) {
193 return std::make_pair(
true, 0);
197 auto uniq_sort = create_unique_set(start, end, mask);
198 Type_ last = std::numeric_limits<Type_>::lowest();
199 for (
auto x : uniq_sort) {
200 if (std::isfinite(x)) {
201 Type_ candidate = last + (x - last) / 2;
202 if (candidate != last && candidate != x) {
203 return std::make_pair(
true, candidate);
209 return std::make_pair(
false, 0);
224template<class Iterator, class Type_ = typename std::remove_cv<typename std::remove_reference<decltype(*(std::declval<Iterator>()))>::type>::type>
std::pair< bool, Type_ > choose_missing_integer_placeholder(Iterator start, Iterator end, Mask mask)
Definition choose_missing_placeholder.hpp:89
std::pair< bool, Type_ > choose_missing_float_placeholder(Iterator start, Iterator end, Mask mask, bool skip_nan)
Definition choose_missing_placeholder.hpp:157