Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Classic: Fixed position_iterator forming reference to local #422

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions classic/test/position_iterator_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <cstddef>
#include <boost/config.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/for_each.hpp>

Expand Down Expand Up @@ -479,6 +480,7 @@ void CheckDistance(void)

namespace test_impl {

template <bool AsValue = false>
class check_singular_iterator
{
bool singular_;
Expand All @@ -488,18 +490,18 @@ namespace test_impl {
typedef std::forward_iterator_tag iterator_category;
typedef int value_type;
typedef std::ptrdiff_t difference_type;
typedef int* pointer;
typedef int& reference;
typedef int const* pointer;
typedef typename boost::mpl::if_c<AsValue, int, int const&>::type reference;

check_singular_iterator() : singular_(true), count_(0) {}
explicit check_singular_iterator(int x) : singular_(false), count_(x) {}

int const& operator*() const {
reference operator*() const {
BOOST_TEST(!singular_);
return count_;
}

int const* operator->() const {
pointer operator->() const {
BOOST_TEST(!singular_);
return &count_;
}
Expand All @@ -526,11 +528,11 @@ namespace test_impl {
}
};

template <typename CountIterator>
void CheckSingular()
template <typename CountIterator, typename Iterator>
void CheckSingularImpl()
{
CountIterator begin(check_singular_iterator(5), check_singular_iterator(0));
CountIterator end1(check_singular_iterator(0), check_singular_iterator(0));
CountIterator begin(Iterator(5), Iterator(0));
CountIterator end1(Iterator(0), Iterator(0));
CountIterator end2;

BOOST_TEST(begin == begin);
Expand All @@ -554,24 +556,28 @@ namespace test_impl {

BOOST_TEST(std::distance(end2, end1) == 0);
BOOST_TEST(std::distance(end2, end2) == 0);

BOOST_TEST(*begin == 5);
}

template <typename PositionT>
void CheckSingular()
{
{
typedef check_singular_iterator<false> interator_type;
CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
}
{
typedef check_singular_iterator<true> interator_type;
CheckSingularImpl<position_iterator<interator_type, PositionT>, interator_type>();
CheckSingularImpl<position_iterator2<interator_type, PositionT>, interator_type>();
}
}
}

void CheckSingular()
{
test_impl::CheckSingular<
position_iterator<test_impl::check_singular_iterator, file_position>
>();

test_impl::CheckSingular<
position_iterator<test_impl::check_singular_iterator, file_position_without_column>
>();

test_impl::CheckSingular<
position_iterator2<test_impl::check_singular_iterator, file_position>
>();

test_impl::CheckSingular<
position_iterator2<test_impl::check_singular_iterator, file_position_without_column>
>();
test_impl::CheckSingular<file_position>();
test_impl::CheckSingular<file_position_without_column>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ private:

/* namespace boost::spirit { */ namespace iterator_ { namespace impl {

template <typename T>
struct make_const : boost::add_const<T>
{};

template <typename T>
struct make_const<T&>
{
typedef typename boost::add_const<T>::type& type;
};

///////////////////////////////////////////////////////////////////////////////
//
// position_iterator_base_generator
Expand All @@ -107,6 +117,7 @@ private:
typedef boost::detail::iterator_traits<ForwardIterT> traits;
typedef typename traits::value_type value_type;
typedef typename traits::iterator_category iter_category_t;
typedef typename traits::reference reference;

// Position iterator is always a non-mutable iterator
typedef typename boost::add_const<value_type>::type const_value_type;
Expand All @@ -125,7 +136,8 @@ public:
main_iter_t,
ForwardIterT,
const_value_type,
boost::forward_traversal_tag
boost::forward_traversal_tag,
typename make_const<reference>::type
> type;
};

Expand Down