Created
October 26, 2016 18:02
-
-
Save elfsternberg/6f096fd9f0755a864cb16812ec294eb8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <tuple> | |
#include <iostream> | |
#include <vector> | |
#include <list> | |
#include <algorithm> | |
#include <iterator> | |
/* This is an attempt to translate the Boost-oriented demo of C++14 | |
from the O'Reilly handout "C++ Today: The Beast Is Back" | |
(http://www.oreilly.com/programming/free/files/c++-today.pdf) into | |
something both GCC 4.8.5 and Clang 3.9.1 can understand and use | |
without Boost. | |
A bit got lost in translation; Boost's "iterator_value_type" is a | |
loose revision of std::iterator_traits<T>::value_type, and even if | |
I am moving the tuple back to the calling space, the tuple type | |
can't be auto-cast, which I think was part of the original demo. | |
Where they return {count, minimum, maximum}, I had to provide the | |
type as a templated typename, which was disappointing, to work | |
around the explicit constructor limitations in std::tuple<T...>. | |
On the other hand, I was able to exchange the primitive while() | |
loop with a lambda, which makes me very happy. This code actually | |
passes both clang-tidy (c++1y mode) and cppcheck (c++11 mode) | |
without a single complaint. | |
*/ | |
template <typename ConstInputIterator, | |
typename MinMaxType = typename std::iterator_traits<ConstInputIterator>::value_type, | |
typename ResultType = std::tuple<size_t, MinMaxType, MinMaxType>> | |
auto lenminmax(ConstInputIterator first, ConstInputIterator last) -> ResultType | |
{ | |
if (first == last) { return ResultType(0, 0, 0); } | |
auto count = size_t{1}; | |
auto minimum(*first); | |
auto maximum(minimum); // only evaluate *first once | |
for_each(first, last, [&minimum, &maximum, &count](MinMaxType &value) { | |
if (value < minimum) { minimum = value; } | |
if (value > maximum) { maximum = value; } | |
count++; | |
}); | |
return ResultType(count, minimum, maximum); | |
} | |
/* std::tie and std::ignore are provided by std::tuple; std::tie | |
allows you to receive multiple return values, and std::ignore tells | |
the compiler that a particular return value is of no interest to | |
the receiving function. | |
*/ | |
int main() { | |
std::vector<int> samples {5, 3, 2, 4, 8, 9, 13, 12}; | |
int min, max; | |
std::tie(std::ignore, min, max) = lenminmax(samples.begin(), samples.end()); | |
std::cout << "Minimun: " << min << ", Maximum: " << max << std::endl; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment