Skip to content

Instantly share code, notes, and snippets.

@elfsternberg
Created October 26, 2016 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elfsternberg/6f096fd9f0755a864cb16812ec294eb8 to your computer and use it in GitHub Desktop.
Save elfsternberg/6f096fd9f0755a864cb16812ec294eb8 to your computer and use it in GitHub Desktop.
#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