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

string_proxy don't know how to compare #191

Closed
romainfrancois opened this issue Oct 13, 2014 · 5 comments
Closed

string_proxy don't know how to compare #191

romainfrancois opened this issue Oct 13, 2014 · 5 comments

Comments

@romainfrancois
Copy link
Contributor

#include <Rcpp.h>
using namespace Rcpp ;

// [[Rcpp::export]]
bool all_equal( CharacterVector x, CharacterVector y){
  return std::equal( x.begin(), x.end(), y.begin() ) ;
}


/*** R
  all_equal( c("a", "b"), c("a", "b") )
*/

I get this because of ambiguities because the operator==( string_proxy, string_proxy ) is not defined.

 RcppScript /tmp/test.cpp
In file included from test.cpp:1:
In file included from /Library/Frameworks/R.framework/Versions/3.1/Resources/library/Rcpp/include/Rcpp.h:27:
In file included from /Library/Frameworks/R.framework/Versions/3.1/Resources/library/Rcpp/include/RcppCommon.h:29:
In file included from /Library/Frameworks/R.framework/Versions/3.1/Resources/library/Rcpp/include/Rcpp/platform/compiler.h:171:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/map:423:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__tree:18:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:658:97: error: use of overloaded operator '==' is ambiguous
      (with operand types 'const Rcpp::internal::string_proxy<16>' and 'const Rcpp::internal::string_proxy<16>')
    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
                                                                                            ~~~ ^  ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1164:14: note: in instantiation of member function
      'std::__1::__equal_to<Rcpp::internal::string_proxy<16>, Rcpp::internal::string_proxy<16> >::operator()' requested here
        if (!__pred(*__first1, *__first2))
             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1176:19: note: in instantiation of function template
      specialization 'std::__1::equal<Rcpp::internal::Proxy_Iterator<Rcpp::internal::string_proxy<16> >, Rcpp::internal::Proxy_Iterator<Rcpp::internal::string_proxy<16> >,
      std::__1::__equal_to<Rcpp::internal::string_proxy<16>, Rcpp::internal::string_proxy<16> > >' requested here
    return _VSTD::equal(__first1, __last1, __first2, __equal_to<__v1, __v2>());
                  ^
test.cpp:6:15: note: in instantiation of function template specialization 'std::__1::equal<Rcpp::internal::Proxy_Iterator<Rcpp::internal::string_proxy<16> >,
      Rcpp::internal::Proxy_Iterator<Rcpp::internal::string_proxy<16> > >' requested here
  return std::equal( x.begin(), x.end(), y.begin() ) ;
              ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:658:97: note: built-in candidate operator==(struct SEXPREC *,
      struct SEXPREC *)
    _LIBCPP_INLINE_VISIBILITY bool operator()(const _T1& __x, const _T1& __y) const {return __x == __y;}
                                                                                                ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:658:97: note: built-in candidate operator==(const struct
      SEXPREC *, const struct SEXPREC *)
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:658:97: note: built-in candidate operator==(char *, char *)
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:658:97: note: built-in candidate operator==(const char *,
      const char *)
1 error generated.
make: *** [test.o] Error 1
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG  -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include  -I"/Library/Frameworks/R.framework/Versions/3.1/Resources/library/Rcpp/include"    -fPIC  -O3 -c test.cpp -o test.o
Erreur dans sourceCpp(tail(args, 1), verbose = "-v" %in% args) :
  Error 1 occurred building shared library.
Exécution arrêtée

Could have used this in dplyr here:
https://github.com/hadley/dplyr/blob/5fe733ced5cce12d03787ca2d350b1f75edf95ac/inst/include/dplyr/JoinFactorFactorVisitor_SameLevels.h#L13

instead I had to write the manual loop:

        for( int i=0; i<n; i++) {
            if( levels_right[i] != levels_left[i] ) return false ;
        }       
@romainfrancois
Copy link
Contributor Author

BTW:

$  Rcpp11Script /tmp/test.cpp

> all_equal(c("a", "b"), c("a", "b"))
[1] TRUE

@hadley
Copy link
Contributor

hadley commented Feb 19, 2015

Similarly, String and string_proxy don't know how to compare:

int findString(CharacterVector haystack, String needle) {
  for (int i = 0; i < haystack.size(); ++i)
    if (haystack[i] == needle)
      return i;

  return -1;
}

@dcdillon
Copy link
Contributor

Ok. So I took a look at this and fundamentally something needs to be defined. Specifically what it means for Strings and string_proxy to compare.

Rcpp::String::opreator== is defined as:

bool operator==( const Rcpp::String& other) const {
        return get_sexp() == other.get_sexp() ;
}

So this means that two Rcpp::Strings are only == if they are the exact same object (unless I am reading this wrong).

So, to keep paradigms the same, any comparison between string_proxy and string_proxy should follow the same pattern.

Additionally any comparison between String and string_proxy is more or less destined to fail if it follows the same paradigm.

So the question "what does string equality comparison mean?" needs to be answered before this issue can be addressed in a reasonable way.

As an aside, for Rcpp::String there is a weird situation as follows:

Rcpp::String a("abc");
Rcpp::String b("abc");

bool equalWithLessThan = (!(a < b)) && (!(b < a));
bool equalWithDoubleEquals = (a == b);
ASSERT(equalWithLessThan == equalWithDoubleEquals); // fails

@eddelbuettel
Copy link
Member

This must have gotten fixed during one of the 0.11.* releases. Taking Romain's example from above and putting it into /tmp/foo.cpp leaves us with:

R> sourceCpp("/tmp/foo.cpp")

R>   all_equal( c("a", "b"), c("a", "b") )
[1] TRUE
R> 

so I'll close this.

@romainfrancois
Copy link
Contributor Author

Note that testing equality of the underlying pointers is not good enough as it fails to handle equal strings that have different encodings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants