diff --git a/libraries/chain/message_handling_contexts.cpp b/libraries/chain/message_handling_contexts.cpp index 098872c5cd7..9501b1e126b 100644 --- a/libraries/chain/message_handling_contexts.cpp +++ b/libraries/chain/message_handling_contexts.cpp @@ -4,11 +4,10 @@ #include #include +#include + #include #include -#include -#include -#include namespace eos { namespace chain { @@ -48,15 +47,7 @@ bool apply_context::all_authorizations_used() const { } vector apply_context::unused_authorizations() const { - auto RemoveUsed = boost::adaptors::filtered([](const auto& tuple) { - return !boost::get<0>(tuple); - }); - auto ToPermission = boost::adaptors::transformed([](const auto& tuple) { - return boost::get<1>(tuple); - }); - - // zip the parallel arrays, filter out the used authorizations, and return just the permissions that are left - auto range = boost::combine(used_authorizations, msg.authorization) | RemoveUsed | ToPermission; + auto range = utilities::FilterDataByMarker(msg.authorization, used_authorizations, false); return {range.begin(), range.end()}; } diff --git a/libraries/utilities/include/eos/utilities/parallel_markers.hpp b/libraries/utilities/include/eos/utilities/parallel_markers.hpp new file mode 100644 index 00000000000..e59b5ba6708 --- /dev/null +++ b/libraries/utilities/include/eos/utilities/parallel_markers.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +namespace eos { namespace utilities { + +/** + * @brief Return values in DataRange corresponding to matching Markers + * + * Takes two parallel ranges, a Data range containing data values, and a Marker range containing markers on the + * corresponding data values. Returns a new Data range containing only the values corresponding to markers which match + * markerValue + * + * For example: + * @code{.cpp} + * vector data = {'A', 'B', 'C'}; + * vector markers = {true, false, true}; + * auto markedData = FilterDataByMarker(data, markers, true); + * // markedData contains {'A', 'C'} + * @endcode + */ +template +DataRange FilterDataByMarker(DataRange data, MarkerRange markers, const Marker& markerValue) { + auto RemoveMismatchedMarkers = boost::adaptors::filtered([&markerValue](const auto& tuple) { + return boost::get<0>(tuple) == markerValue; + }); + auto ToData = boost::adaptors::transformed([](const auto& tuple) { + return boost::get<1>(tuple); + }); + + // Zip the ranges together, filter out data with markers that don't match, and return the data without the markers + auto range = boost::combine(markers, data) | RemoveMismatchedMarkers | ToData; + return {range.begin(), range.end()}; +} + +}} // namespace eos::utilities +