LUMIERA.clone/tests/library/util-collection-test.cpp
Ichthyostega 8c12e88fd3 C++17: fix detector for STL container iterability
the reason for the failure, as it turned out,
is that 'noexcept' is part of the function signature since C++17

And, since typically a STL container has const and non-const variants
of the begin() and end() function, the match to a member function pointer
became ambuguous, when probing with a signature without 'noexcept'

However, we deliberately want to support "any STL container like" types,
and this IMHO should include types with a possibly throwing iterator.
The rationale is, sometimes we want to expose some element *generator*
behind a container-like interface.

At this point I did an investigation if we can emulate something
in the way of a Concept -- i.e. rather than checking for the presence
of some functions on the interface, better try to cover the necessary
behaviour, like in a type class.

Unfortunately, while doable, this turns out to become quite technical;
and this highlights why the C++20 concepts are such an important addition
to the language.

So for the time being, we'll amend the existing solution
and look ahead to C++20
2020-02-21 18:57:49 +01:00

137 lines
3.3 KiB
C++

/*
UtilCollection(Test) - helpers and shortcuts for working with collections
Copyright (C) Lumiera.org
2012, Hermann Vosseler <Ichthyostega@web.de>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file util-collection-test.cpp
** unit test \ref UtilCollection_test
*/
#include "lib/test/run.hpp"
#include "lib/itertools.hpp"
#include "lib/util-coll.hpp"
#include "lib/iter-adapter.hpp"
#include "lib/meta/trait.hpp"
#include <boost/lexical_cast.hpp>
#include <vector>
using ::Test;
using util::first;
using util::last;
using lib::meta::can_STL_ForEach;
using lib::meta::can_IterForEach;
using lib::meta::can_STL_backIteration;
using boost::lexical_cast;
namespace util {
namespace test {
typedef std::vector<uint> VecI;
typedef lib::RangeIter<VecI::iterator> RangeI;
namespace{ // Test data and operations
uint NUM_ELMS = 20;
VecI
someNumberz (uint count)
{
VecI numbers;
numbers.reserve(count);
while (count)
numbers.push_back(count--);
return numbers;
}
} // (End) test data and operations
/*****************************************************************//**
* @test verify some convenience shortcuts and helpers dealing
* with Collections and sequences (Iterators).
* - metafunctions to distinguish STL containers and Lumiera Iterators
* - get the first element
* - get the last element
*/
class UtilCollection_test : public Test
{
void
run (Arg arg)
{
verify_typeDetectors();
if (0 < arg.size()) NUM_ELMS = lexical_cast<uint> (arg[0]);
VecI container = someNumberz (NUM_ELMS);
RangeI iterator(container.begin(), container.end());
verify_accessFirstLast (container, NUM_ELMS);
verify_accessFirstLast (iterator, NUM_ELMS);
}
template<class COL>
void
verify_accessFirstLast (COL const& col, uint lim)
{
uint theFirst = lim;
uint theLast = 1;
CHECK (first(col) == theFirst);
CHECK (last(col) == theLast);
}
void
verify_typeDetectors()
{
CHECK ( can_STL_ForEach<VecI>::value);
CHECK ( can_STL_backIteration<VecI>::value);
CHECK (!can_STL_ForEach<RangeI>::value);
CHECK (!can_STL_backIteration<RangeI>::value);
CHECK (!can_IterForEach<VecI>::value);
CHECK ( can_IterForEach<RangeI>::value);
}
};
LAUNCHER (UtilCollection_test, "unit common");
}} // namespace util::test