2

I am first converting an utf-8 string to utf-32 and then I want unique words to be mapped with their positions. I started with boost locale.

#include <iostream>
#include <string>
#include <chrono>
#include <boost/shared_ptr.hpp>
#include <map>
#include <list>
#include <boost/locale.hpp>

typedef std::u32string string_type;
typedef std::pair<unsigned long, unsigned long> range_type;
typedef std::map<std::string, std::list<range_type>> wordref_type;

struct parser{
    /**
     * returns a map of "words" with its positions list
     */
    static wordref_type parse(string_type::const_iterator b, string_type::const_iterator e){
        wordref_type wordrefs;
        range_type sentence;

        boost::locale::boundary::segment_index<string_type::const_iterator> index(boost::locale::boundary::word, b, e);
        //TODO: iterate index
        return wordrefs;
    }
};

int main(int argc, char** argv){
    std::string input_str = "Some UTF-8 texts";
    string_type buffer = boost::locale::conv::utf_to_utf<string_type::value_type>(input_str); // convert utf-8 to utf-32
    wordref_type wordrefs = parser::parse(buffer.cbegin(), buffer.cend());
    return 0;
}

It complains invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing<char32_t>’. What is wrong ? I have Ideone'ed it

In file included from /usr/include/boost/locale/boundary.hpp:15:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/index.hpp: In instantiation of ‘static boost::locale::boundary::index_type boost::locale::boundary::details::mapping_traits<IteratorType, std::random_access_iterator_tag>::map(boost::locale::boundary::boundary_type, IteratorType, IteratorType, const std::locale&) [with IteratorType = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::index_type = std::vector<boost::locale::boundary::break_info>]’:
/usr/include/boost/locale/boundary/index.hpp:126:83:   required from ‘boost::locale::boundary::details::mapping<BaseIterator>::mapping(boost::locale::boundary::boundary_type, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::details::mapping<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
/usr/include/boost/locale/boundary/index.hpp:631:43:   required from ‘boost::locale::boundary::segment_index<BaseIterator>::segment_index(boost::locale::boundary::boundary_type, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::segment_index<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
prog.cpp:21:118:   required from here
/usr/include/boost/locale/boundary/index.hpp:98:93: error: invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing<char32_t>’
                             index_type tmp=std::use_facet<boundary_indexing<char_type> >(l).map(t,begin,end);
                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/boost/locale/boundary.hpp:12:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/facets.hpp:90:19: note: declaration of ‘class boost::locale::boundary::boundary_indexing<char32_t>’
             class boundary_indexing;
                   ^~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/locale/boundary.hpp:15:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/index.hpp:103:95: error: invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing<char32_t>’
                             index_type tmp = std::use_facet<boundary_indexing<char_type> >(l).map(t,str.c_str(),str.c_str()+str.size());
                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/boost/locale/boundary.hpp:12:0,
                 from /usr/include/boost/locale.hpp:11,
                 from prog.cpp:7:
/usr/include/boost/locale/boundary/facets.hpp:90:19: note: declaration of ‘class boost::locale::boundary::boundary_indexing<char32_t>’
             class boundary_indexing;
                   ^~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/6/bits/locale_classes.h:850:0,
                 from /usr/include/c++/6/bits/ios_base.h:41,
                 from /usr/include/c++/6/ios:42,
                 from /usr/include/c++/6/ostream:38,
                 from /usr/include/c++/6/iostream:39,
                 from prog.cpp:1:
/usr/include/c++/6/bits/locale_classes.tcc: In instantiation of ‘const _Facet& std::use_facet(const std::locale&) [with _Facet = boost::locale::boundary::boundary_indexing<char32_t>]’:
/usr/include/boost/locale/boundary/index.hpp:98:89:   required from ‘static boost::locale::boundary::index_type boost::locale::boundary::details::mapping_traits<IteratorType, std::random_access_iterator_tag>::map(boost::locale::boundary::boundary_type, IteratorType, IteratorType, const std::locale&) [with IteratorType = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::index_type = std::vector<boost::locale::boundary::break_info>]’
/usr/include/boost/locale/boundary/index.hpp:126:83:   required from ‘boost::locale::boundary::details::mapping<BaseIterator>::mapping(boost::locale::boundary::boundary_type, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, boost::locale::boundary::details::mapping<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::details::mapping<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
/usr/include/boost/locale/boundary/index.hpp:631:43:   required from ‘boost::locale::boundary::segment_index<BaseIterator>::segment_index(boost::locale::boundary::boundary_type, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, boost::locale::boundary::segment_index<BaseIterator>::base_iterator, const std::locale&) [with BaseIterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >; boost::locale::boundary::segment_index<BaseIterator>::base_iterator = __gnu_cxx::__normal_iterator<const char32_t*, std::__cxx11::basic_string<char32_t> >]’
prog.cpp:21:118:   required from here
/usr/include/c++/6/bits/locale_classes.tcc:134:37: error: incomplete type ‘boost::locale::boundary::boundary_indexing<char32_t>’ used in nested name specifier
       const size_t __i = _Facet::id._M_id();


                ~~~~~~~~~~~^~~~~
Neel Basu
  • 12,638
  • 12
  • 82
  • 146

2 Answers2

2

It complains invalid use of incomplete type ‘const class boost::locale::boundary::boundary_indexing’ What's wrong?

char32_t is not supported. Use

#define BOOST_LOCALE_ENABLE_CHAR32_T

But you need to enable it during building the library, as well:

Experimental support for C++0x char16_t and char32_t strings and streams.

Further looking: http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/status_of_cpp0x_characters_support.html

If you want to build or test Boost.Locale with C++11 char16_t and char32_t support you should pass cxxflags="-DBOOST_LOCALE_ENABLE_CHAR32_T -DBOOST_LOCALE_ENABLE_CHAR16_T" to b2 during build and define BOOST_LOCALE_ENABLE_CHAR32_T and BOOST_LOCALE_ENABLE_CHAR32_T when using Boost.Locale

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Now I am getting linker Error `Undefined symbols for architecture x86_64: "boost::locale::boundary::boundary_indexing::id", referenced` But In my CMakeLists.txt file I have `FIND_PACKAGE(Boost COMPONENTS filesystem regex locale REQUIRED)`. locale is there. – Neel Basu Feb 14 '18 at 15:36
  • Didn't I just put that in my answer? The library *needs* to be built with those flags. – sehe Feb 14 '18 at 15:46
  • Headsup: on my box the standard library support for char32_t (most likely locale facets) is not sufficient to build the experimental support (that's Ubuntu 16.04 with gcc 5.x or gcc 7.x with and the corresponding libstdc++ (also with Clang5)). E.g.: https://paste.ubuntu.com/p/MpW5jwcfPh/ – sehe Feb 14 '18 at 16:17
  • Just encountered the same on Ubuntu 18.04 (gcc 7.3, https://paste.ubuntu.com/p/6TmyHwHNNh/) – sehe Feb 14 '18 at 16:30
1

You need to compile boost with BOOST_LOCALE_ENABLE_CHAR32_T to include the boundary_indexing<char32_t> but ...

Status of C++11 char16_t/char32_t support

The support of C++11 char16_t and char32_t is experimental, mostly does not work and not intended to be used in production with current latest compilers: GCC-4.5, MSVC10 till major compiler's flaws would be fixed.

[....]

If you want to build or test Boost.Locale with C++11 char16_t and char32_t support you should pass cxxflags="-DBOOST_LOCALE_ENABLE_CHAR32_T -DBOOST_LOCALE_ENABLE_CHAR16_T" to b2 during build and define BOOST_LOCALE_ENABLE_CHAR32_T and BOOST_LOCALE_ENABLE_CHAR32_T when using Boost.Locale

[emphasis mine]

http://www.boost.org/doc/libs/1_66_0/libs/locale/doc/html/facets_8hpp_source.html

#ifdef BOOST_LOCALE_ENABLE_CHAR32_T
template<>
class BOOST_LOCALE_DECL boundary_indexing<char32_t> : public std::locale::facet {
Mihayl
  • 3,821
  • 2
  • 13
  • 32
  • Now I am getting linker error `Undefined symbols for architecture x86_64: "boost::locale::boundary::boundary_indexing::id", referenced`. I have locale added in `FIND_PACKAGE(Boost COMPONENTS filesystem regex locale REQUIRED)` – Neel Basu Feb 14 '18 at 15:36
  • @NeelBasu define is not enough, you have to compile it with the define – Mihayl Feb 14 '18 at 15:38
  • But I installed it through brew. How can I reinstall it with brew with utf32 support ? – Neel Basu Feb 14 '18 at 15:38
  • @NeelBasu That's a new question. Likely, more on-topic on another site – sehe Feb 14 '18 at 15:49
  • Not sure but you could try to export the define to `cxxflags=-DBOOST_LOCALE_ENABLE_CHAR32_T` before installing boost. Or maybe you'll need to modify the Boost.rb and add the define to `args << "cxxflags=` – Mihayl Feb 14 '18 at 16:02
  • It's a command line option, as the documentation says. But, as I report in the comments on my answer, it is truly experimental, which is reflected in the fact that it doesn't actually build on distro standard versions of the standard library. I don't think `Boost.rb` is ever to be modified, unless that is a new feature replacing the user/project configs – sehe Feb 14 '18 at 16:48
  • @sehe i have no experience with *brew*, i also wouldn't modify it. – Mihayl Feb 14 '18 at 17:31
  • Oh aha. The .rb is part of Brew. That explains that I didn't recognize it. No, obviously you shouldn't hack that (unless you want to make your own Brew packages). Regardless, chances are that the support is not going to compile on the platform – sehe Feb 14 '18 at 18:47