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

Issue using std::sort with Exiv2::ExifData: operator- not defined #1423

Closed
phako opened this issue Dec 8, 2020 · 5 comments
Closed

Issue using std::sort with Exiv2::ExifData: operator- not defined #1423

phako opened this issue Dec 8, 2020 · 5 comments
Assignees
Labels
enhancement feature / functionality enhancements
Milestone

Comments

@phako
Copy link
Contributor

phako commented Dec 8, 2020

Describe the bug
I need to define a custom collation function for sorting metadata by key (exiv2 bug #1424). I am using std::sort for this:

    // get a copy of the ExifData and sort it by tags, preserving sort of original
    Exiv2::ExifData exif_data = Exiv2::ExifData(self->priv->image->exifData());
    std::sort(exif_data.begin(), exif_data.end(), [](Exiv2::Exifdatum& a, Exiv2::Exifdatum& b) {
        return collate_key(a.key()) < collate_key(b.key());
    });

This results in

In file included from /usr/include/c++/10/algorithm:62,
                 from ../gexiv2/gexiv2/gexiv2-metadata-private.h:13,
                 from ../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:12:
/usr/include/c++/10/bits/stl_algo.h: In instantiation of ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<Exiv2::Exifdatum>; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<gexiv2_metadata_get_exif_tags(GExiv2Metadata*)::<lambda(Exiv2::Exifdatum&, Exiv2::Exifdatum&)> >]’:
/usr/include/c++/10/bits/stl_algo.h:4894:18:   required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = std::_List_iterator<Exiv2::Exifdatum>; _Compare = gexiv2_metadata_get_exif_tags(GExiv2Metadata*)::<lambda(Exiv2::Exifdatum&, Exiv2::Exifdatum&)>]’
../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:78:6:   required from here
/usr/include/c++/10/bits/stl_algo.h:1975:22: error: no match for ‘operator-’ (operand types are ‘std::_List_iterator<Exiv2::Exifdatum>’ and ‘std::_List_iterator<Exiv2::Exifdatum>’)
 1975 |     std::__lg(__last - __first) * 2,
      |               ~~~~~~~^~~~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/algorithm:61,
                 from ../gexiv2/gexiv2/gexiv2-metadata-private.h:13,
                 from ../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:12:
/usr/include/c++/10/bits/stl_iterator.h:525:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> decltype ((__y.base() - __x.base())) std::operator-(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)’
  525 |     operator-(const reverse_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:525:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/algorithm:62,
                 from ../gexiv2/gexiv2/gexiv2-metadata-private.h:13,
                 from ../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:12:
/usr/include/c++/10/bits/stl_algo.h:1975:22: note:   ‘std::_List_iterator<Exiv2::Exifdatum>’ is not derived from ‘const std::reverse_iterator<_Iterator>’
 1975 |     std::__lg(__last - __first) * 2,
      |               ~~~~~~~^~~~~~~~~
In file included from /usr/include/c++/10/bits/stl_algobase.h:67,
                 from /usr/include/c++/10/algorithm:61,
                 from ../gexiv2/gexiv2/gexiv2-metadata-private.h:13,
                 from ../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:12:
/usr/include/c++/10/bits/stl_iterator.h:1566:5: note: candidate: ‘template<class _IteratorL, class _IteratorR> decltype ((__x.base() - __y.base())) std::operator-(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)’
 1566 |     operator-(const move_iterator<_IteratorL>& __x,
      |     ^~~~~~~~
/usr/include/c++/10/bits/stl_iterator.h:1566:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/10/algorithm:62,
                 from ../gexiv2/gexiv2/gexiv2-metadata-private.h:13,
                 from ../gexiv2/gexiv2/gexiv2-metadata-exif.cpp:12:
/usr/include/c++/10/bits/stl_algo.h:1975:22: note:   ‘std::_List_iterator<Exiv2::Exifdatum>’ is not derived from ‘const std::move_iterator<_IteratorL>’
 1975 |     std::__lg(__last - __first) * 2,
      |               ~~~~~~~^~~~~~~~~

The same works fine for Exiv2::XmpData and Exiv2::IptcData.
To Reproduce
See description. I have only been able to test this with exiv2 0.27.3

  1. Provide the image with which you observed the issue (commonly named PoC)
  2. Provide exact command to reproduce the issue
  3. Mention the branch/commit in which you observed the issue (i.e: master or 0.27-maintenance)

Expected behavior
A clear and concise description of what you expected to happen.

Desktop (please complete the following information):

  • OS: Fedora 33
  • Compiler & Version [GCC 10.2.1]
  • Compilation mode and/or compiler flags -> Whatever Fedora does in its packaging process
@phako phako added the bug label Dec 8, 2020
@clanmills clanmills added request feature request or any other kind of wish and removed bug labels Dec 8, 2020
@clanmills
Copy link
Collaborator

clanmills commented Dec 8, 2020

This is correct behaviour. The class is derived from std::list and does not support std::sort. I agree that it is inconsistent to derived XmpData and IptcData from std::vector and ExifData from std::list.

Currently sorting is implemented in ExifData::sortByKey(), IptcData::sortByKey() and XmpData::sortByKey(). Exif and Iptc also have a sortByTag() method.

So, I think this is an enhancement request to say: Please derive the classes ExifData, XmpData and IptcData from a common base which supports std::sort. The word "Please" is optional!

@clanmills
Copy link
Collaborator

I can't change this on the 0.27-maintenance branch because it would change the API. It'll have to be dealt with in 'master' and therefore 0.28.

@clanmills clanmills added enhancement feature / functionality enhancements and removed request feature request or any other kind of wish labels Dec 10, 2020
@clanmills
Copy link
Collaborator

@phako Andreas changed it from vector to list. https://dev.exiv2.org/projects/exiv2/repository/exiv2/revisions/2017

Curious, no? I don't know why. You could try searching the log to discover why this was changed.

@clanmills
Copy link
Collaborator

It is possible he wanted to preserve the order of the Exif keys. That's of little importance for XMP because RDF is a random access tree structure. IPTC are several dictionaries. (Envelope = 1, Application = 2). Don't know the reason for the change to std::list.

@clanmills clanmills self-assigned this Mar 11, 2021
@clanmills
Copy link
Collaborator

#1424 (comment)

@clanmills clanmills added this to the v0.27.4 milestone Mar 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature / functionality enhancements
Projects
None yet
Development

No branches or pull requests

2 participants