March 29, 2005
Chris, et al.

Here's an example project demonstrating the use of PlatformSTL's memory_mapped_file with STLSoft's string_view.

The bit to note is that, in the code extract shown below, there is not a single memory allocation (or no call to ::operator new(),  at least), outside the call to the operating system's mmap() (or equiv.). That's pretty good, eh? :-)

You'll also need to put in the new integer_to_string.hpp in "$(STLSOFT_INCLUDE)/inprogress/stlsoft".

Cheers

Matthew

<code>
  /* . */
  if(NULL == inputFileName)
  {
    usage(1, "Must specify file to process", -1, argc, argv);
  }
  else
  {
    // Define the local string type: a string_view on char type
    typedef ::stlsoft::basic_string_view<char>        string_view_t;

    // Declare the mem-map file and string view variables
    ::platformstl::memory_mapped_file mmf(inputFileName);
    string_view_t                     sv(static_cast<char const *>(mmf.memory()), mmf.size());

    // Now we'll do things with it

    // 0. Define the delimiter for the ambient operating system
#if defined(PLATFORMSTL_OS_IS_UNIX)
    const string_view_t         delimiter("\n", 1);
#elif defined(PLATFORMSTL_OS_IS_WIN32)
    const string_view_t         delimiter("\r\n", 2);
#else
# error Operating system not discriminated
#endif /* platform */

    // 1. Count the number of chars
    {
      size_t  numChars  = std::distance(sv.begin(), sv.end());

      cout << "Number of characters:            " << numChars << endl;
    }

    // 2. Count the number of lines (using stlsoft::string_tokeniser)
    {
      typedef ::stlsoft::string_tokeniser<  string_view_t
                        , string_view_t
                        , ::stlsoft::string_tokeniser_ignore_blanks<false>
                        >           tokeniser_keep_blanks_t;

      tokeniser_keep_blanks_t lines(sv.begin(), sv.end(), delimiter);
      size_t                  numLines  = ::std::distance(lines.begin(), lines.end());

      cout << "Number of lines:                 " << numLines << endl;
    }

    // 3. Count the number of non-blank lines (using stlsoft::string_tokeniser)
    {
      typedef ::stlsoft::string_tokeniser<  string_view_t
                        , string_view_t
                        >           tokeniser_t;

      tokeniser_t lines(sv.begin(), sv.end(), delimiter);
      size_t      numLines  = ::std::distance(lines.begin(), lines.end());

      cout << "Number of lines (non-blank):     " << numLines << endl;
    }

    // 4. Count the number of lines (using stlsoft::string_tokeniser + rangelib stuff)
    {
      typedef ::stlsoft::string_tokeniser<  string_view_t
                        , string_view_t
                        , ::stlsoft::string_tokeniser_ignore_blanks<false>
                        >           tokeniser_keep_blanks_t;

      size_t  numLines = ::rangelib::r_distance(rangelib::make_sequence_range(tokeniser_keep_blanks_t(sv.begin(),
sv.end(), delimiter)));

      cout << "Number of lines (R):             " << numLines << endl;
    }

    // 5. Count the number of lines (using stlsoft::string_tokeniser + rangelib stuff)
    {
      typedef ::stlsoft::string_tokeniser<  string_view_t
                        , string_view_t
                        >           tokeniser_t;

      size_t  numLines = ::rangelib::r_distance(rangelib::make_sequence_range(tokeniser_t(sv.begin(), sv.end(),
delimiter)));

      cout << "Number of lines (non-blank) (R): " << numLines << endl;
    }

    // 6. Display each line, indexed (using stlsoft::string_tokeniser + rangelib stuff)
    {
      typedef ::stlsoft::string_tokeniser<  string_view_t
                        , string_view_t
                        , ::stlsoft::string_tokeniser_ignore_blanks<false>
                        >             tokeniser_t;
      typedef ::rangelib::sequence_range<   tokeniser_t>      tokenised_sequence_t;
      typedef ::rangelib::indexed_range<    tokenised_sequence_t
                        , size_t
                        >             indexed_tokenised_sequence_t;

      indexed_tokenised_sequence_t  ir(tokenised_sequence_t(tokeniser_t(sv.begin(), sv.end(), delimiter)));

      cout << "Lines:" << endl;
      for(; ir; ++ir)
      {
        cout << ir.index() << ": " << *ir << endl;
      }
    }
  }
</code>