title: Why mapped_file::data returns char* instead of void*
body: <p>Or even better a template <code>&lt;T*&gt;</code>?</p>
  
  <p>In case the memory mapped file contains a sequence of 32 bit integers, if <code>data()</code> returned a <code>void*</code>, we could be able to static cast to <code>std::uint32_t</code> directly.</p>
  
  <p>Why did boost authors choose to return a <code>char*</code> instead?</p>
  
  <p>EDIT: as pointed out, in case portability is an issue, a translation is needed. But saying that a file (or a chunk of memory in this case) is a stream of bytes more than it is a stream of bits, or of IEEE754 doubles, or of complex data structures, seems to me a very broad statement that needs some more explanation.</p>
  
  <p>Even having to handle endianness, being able to directly map to a vector of <code>be_uint32_t</code> as suggested (and as implemented here) would make the code much more readable:</p>
  
  <pre><code>struct be_uint32_t {
    std::uint32_t raw;
    operator std::uint32_t() { return ntohl(raw); }
  };
  
  static_assert(sizeof(be_uint32_t)==4, "POD failed");
  </code></pre>
  
  <p>Is it allowed/advised to cast to a <code>be_uint32_t*</code>? Why, or why not?</p>
  
  <p>Which kind of cast should be used?</p>
  
  <p><strong>EDIT2</strong>: Since it seems difficult to get to the point instead of discussing weather the memory model of an elaborator is made of bits, bytes or words I will rephrase giving an example:</p>
  
  <pre><code>#include &lt;cstdint&gt;
  #include &lt;memory&gt;
  #include &lt;vector&gt;
  #include &lt;iostream&gt;
  #include &lt;boost/iostreams/device/mapped_file.hpp&gt;
  
  struct entry {
    std::uint32_t a;
    std::uint64_t b;
  } __attribute__((packed)); /* compiler specific, but supported 
                                in other ways by all major compilers */
  
  static_assert(sizeof(entry) == 12, "entry: Struct size mismatch");
  static_assert(offsetof(entry, a) == 0, "entry: Invalid offset for a");
  static_assert(offsetof(entry, b) == 4, "entry: Invalid offset for b");
  
  int main(void) {
    boost::iostreams::mapped_file_source mmap("map");
    assert(mmap.is_open());
    const entry* data_begin = reinterpret_cast&lt;const entry*&gt;(mmap.data());
    const entry* data_end = data_begin + mmap.size()/sizeof(entry);
    for(const entry* ii=data_begin; ii!=data_end; ++ii)
      std::cout &lt;&lt; std::hex &lt;&lt; ii-&gt;a &lt;&lt; " " &lt;&lt; ii-&gt;b &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p>Given that the <code>map</code> file contains the bit expected in the correct order, is there any other reason to avoid using the reinterpret_cast to use my virtual memory without copying it first?</p>
  
  <p>If there is not, why force the user to do a reinterpret_cast by returning a typed pointer?</p>
  
  <p><strong>Please answer all the questions for bonus points :)</strong></p>