thomasmoelhave / tpie

Templated Portable I/O Environment
Other
112 stars 24 forks source link

Cannot compile tests with MSC 19.28+ #269

Open SSoelvsten opened 11 months ago

SSoelvsten commented 11 months ago

With any 19.28+ version of Microsoft's compiler, we get some kind of error similar to the following.

error C2678: binary '=': no operator found which takes a left-hand operand of type 'const tpie::packed_array<bool,1>::iter_return_type' (or there is no acceptable conversion)

This is due to a conflict between tpie::packed_array, its iterator, and Microsoft's implementation of the std::sort (shown below). Specifically, the lines with *_First = _STD move(_Val);, and *_Hole = _STD move(*_Prev) try to write into an iterator that has been marked as const (see the declaration).

template <class _BidIt, class _Pr>
_CONSTEXPR20 _BidIt _Insertion_sort_unchecked(const _BidIt _First, const _BidIt _Last, _Pr _Pred) {
    // insertion sort [_First, _Last)
    if (_First != _Last) {
        for (_BidIt _Mid = _First; ++_Mid != _Last;) { // order next element
            _BidIt _Hole               = _Mid;
            _Iter_value_t<_BidIt> _Val = _STD move(*_Mid);

            if (_DEBUG_LT_PRED(_Pred, _Val, *_First)) { // found new earliest element, move to front
                _Move_backward_unchecked(_First, _Mid, ++_Hole);
                *_First = _STD move(_Val);
            } else { // look for insertion point after first
                for (_BidIt _Prev = _Hole; _DEBUG_LT_PRED(_Pred, _Val, *--_Prev); _Hole = _Prev) {
                    *_Hole = _STD move(*_Prev); // move hole down
                }

                *_Hole = _STD move(_Val); // insert element in hole
            }
        }
    }

    return _Last;
}

This has been identified as part of pull request #257 . But, fixing this issue seems out-of-scope for "Adding CI"? Furthermore, I have no idea how to fix it without any kind of hacks.

SSoelvsten commented 11 months ago

A simple hack would be to add (with a 1928 <=_MSC_VER preprocessor guard?) the following to the tpie::iter_base class for the tpie::packed_array.

iter_return_type & operator*() const
{return const_cast<iter_return_type&>(elm);}

iter_return_type * const operator->() const
{return &elm;}
SSoelvsten commented 11 months ago

If I should be the devil's advocate for Microsoft, I guess the 19.28+ version is based on const iterator_t is supposed to be akin to a T* const whereas TPIE's iterator is a (const T)* const, i.e. the const should only refer to the pointer, not to the pointed value.