2

The iota function was formerly in the <algorithm> header. It has been change to <numeric>.

I need to keep the old way for backward compatibility so I would like to use preprocessor option to select the right header to include.

When does this changed and which preprocessor option should I use?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
jvtrudel
  • 1,235
  • 3
  • 15
  • 28
  • Maybe relevant https://stackoverflow.com/questions/5242524/converting-int-to-string-in-c – Tony J Mar 22 '17 at 18:23
  • 1
    You [test for C++11](http://stackoverflow.com/questions/5047971/how-do-i-check-for-c11-support) and depending on the result you pick which header to use. – NathanOliver Mar 22 '17 at 18:25
  • @TonyJ: That's about `itoa`, not [std::iota](http://en.cppreference.com/w/cpp/algorithm/iota). – Fred Larson Mar 22 '17 at 18:26
  • @NathanOliver yes! something like ````#if __cplusplus <= 199711L```` would be nice. But starting from which version of c++ does it use numeric? – jvtrudel Mar 22 '17 at 18:30
  • @jvtrudel per [this](http://en.cppreference.com/w/cpp/algorithm/iota), C++11 – NathanOliver Mar 22 '17 at 18:31
  • 3
    @jvtrudel: compare against `201103L`. Or you could just include both if it doesn't impact your compile time unacceptably. – Fred Larson Mar 22 '17 at 18:33
  • I know where to find the documentation, but I'm not familiar with the versioning scheme. It don't appear in the documentation as far as I can see @NathanOliver – jvtrudel Mar 22 '17 at 18:37
  • 1
    @jvtrudel Not sure if there is a versioning scheme defined somewhere. You can find the values though in [cpp.predefined] in the standard. (most likely there are using YYYYMM) – NathanOliver Mar 22 '17 at 18:41
  • @FredLarson Oh I just learned something, I read what std::iota does, http://en.cppreference.com/w/cpp/algorithm/iota, but what what does iota stand for? – Tony J Mar 22 '17 at 18:43
  • 2
    @TonyJ as I stated in my answer, iota is the Greek letter ι and the name iota is taken from the programming language APL. It's a Greek letter used in mathematics to denote a set of consecutive numbers. – gsamaras Mar 22 '17 at 18:44
  • `iota` and `itoa` do look dangerously similar. – Fred Larson Mar 22 '17 at 18:53
  • 1
    As far as I can tell, `iota` has been in `` going [all the way back to the SGI STL](https://www.sgi.com/tech/stl/iota.html). When was it in ``? – T.C. Mar 22 '17 at 19:16

3 Answers3

4

iota was never "moved" from <algorithm>. C++03 doesn't have std::iota in any header, and no conforming implementation can provide it, because iota is not a reserved name and this is required to work:

#define iota arbitrary preprocessing token sequence like this and *that and "!" and \
             -13833rfa231fn7or.other.line.noise.that.happens.to.be.a.pp.number
#include <every-standard-header-here>

It was added to <numeric> in C++11 and was in the SGI STL's <numeric> too as an extension. It has never been in <algorithm> and so can't possibly be moved from it.

Now, because standard library headers are allowed to include each other in arbitrary ways, it happens that GCC <= 5's <algorithm> in C++11 mode included <random> by happenstance, which included <numeric> by happenstance. That's a mere implementation detail that you shouldn't be relying upon, and GCC 6 no longer does that. The fix for that is to simply include the correct header, which is, and has always been, <numeric>.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • Interesting... But the compiler that I have seen use ````std::iota```` without ```````` is a mvsc, not gcc. But I do not know the version, that's why I was looking at a change in the STL library. The same (or even worst) mess probably happened their. – jvtrudel Mar 22 '17 at 20:57
1

iota (from the Greek ι) was re-introduced in <numeric> when arrived, as you can see in the ref. So you check if your in an environment without it, and include the old header, or else, include the new header.

Something like this might do the trick:

#if __cplusplus <= 199711L
  #include <algorithm>
#else
  #include <numeric>
#endif

sets the value of __cplusplus to 201103L. That asserts full conformance to the 2011 standard; it doesn't tell you about partial conformance or compiler extensions. If __cplusplus is set to 201103L, then either the compiler fully conforms or it's lying to you. If it's not, then you can't really tell which features it supports.

Read more in this answer.

Moreover, this Quora post also agrees with the change (or to be honest; re-introduce) of std::iota to have happened with .


If you can afford it, just include both libraries.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • I don't need a proof... Just want to understand how to dig in the STL source code and history. Looking at the header source is a good hint, but where is the git/svn of STL? – jvtrudel Mar 22 '17 at 19:11
  • I don't know @jvtrudel, when I had found myself in similar situations digging into the header or/and source files was the way to go! =) – gsamaras Mar 22 '17 at 19:13
  • Do you have any evidence that `iota` has ever been in ``? – T.C. Mar 22 '17 at 19:17
  • Apart from the Quora link @T.C., which mentions its existence, but not its header file, it is evident from this SO [post](http://stackoverflow.com/questions/26579703/iota-increment-vector-of-a-class-c) that at least two humans used from ``. – gsamaras Mar 22 '17 at 19:25
  • 1
    So basically you claim it was "moved in C++11" because of an internal GCC implementation detail (that `` by happenstance pulls in `` which by happenstance pulls in ``)? – T.C. Mar 22 '17 at 19:39
  • I am not sure what you mean @T.C., but I would say it was re-introduced, rather than moved...Updated my answer. – gsamaras Mar 22 '17 at 19:46
  • 1
    I have a collaborator that use it from algorithm; that's why i need preproc option. At least, that's what I guess, but he have a whole bunch of other headers... but not numeric. – jvtrudel Mar 22 '17 at 20:00
1

What you want to do is check if the __cplusplus variable is below a certain point and if it is #include <algorithm> if not then #include <numeric>

#if __cplusplus <= 199711L
  #include <algorithm>
#else
  #include <numeric>
#endif

This should work for just about any library that you need to do this with, just note that you may have to change the 199711L to the appropriate number.

Andria
  • 4,712
  • 2
  • 22
  • 38