Closed GoogleCodeExporter closed 9 years ago
That's too bad; I was really hoping to avoid bringing in iostream here.
iostream is a ginormous header file.
btw, thanks for the clang link; that explains things to me very clearly. I
have a loophole that I think should work, by making the stream a dependent
type. Can you try this patch on libc++ and see what happens? (It may not
apply cleanly due to other changes I have going on, but shouldn't be difficult
to apply manually if need be.)
--- hashtable-common.h#16 2011-11-18 14:23:42.000000000 -0800
+++ hashtable-common.h 2011-12-02 16:05:10.580260000 -0800
@@ -100,18 +100,30 @@
return fwrite(data, length, 1, fp) == 1;
}
-// Lucky these are inline, because we want the caller to be responsible
-// for #including <iostream>, not us (iostream is a big header!)
+// We want the caller to be responsible for #including <iostream>, not
+// us, because iostream is a big header! According to the standard,
+// it's only legal to delay the instantiation the way we want to if
+// the istream/ostream is a template type. So we jump through hoops.
+template<typename ISTREAM>
+inline bool read_data_internal_for_istream(ISTREAM* fp,
+ void* data, size_t length) {
+ return fp->read(reinterpret_cast<char*>(data), length).good();
+}
template<typename Ignored>
inline bool read_data_internal(Ignored*, std::istream* fp,
void* data, size_t length) {
- return fp->read(reinterpret_cast<char*>(data), length).good();
+ return read_data_internal_for_istream(fp, data, length);
}
+template<typename OSTREAM>
+inline bool write_data_internal_for_ostream(OSTREAM* fp,
+ const void* data, size_t length) {
+ return fp->write(reinterpret_cast<const char*>(data), length).good();
+}
template<typename Ignored>
inline bool write_data_internal(Ignored*, std::ostream* fp,
const void* data, size_t length) {
- return fp->write(reinterpret_cast<const char*>(data), length).good();
+ return write_data_internal_for_ostream(fp, data, length);
}
// The INPUT type needs to support a Read() method that takes a
Original comment by csilv...@gmail.com
on 3 Dec 2011 at 12:07
That patch works for me with clang++ with both libstdc++ and libc++.
As a point of interest, I decided to see how bad #include'ing <istream> and
<iostream> was (A friend pointed out that <iostream> is particularly bad
because it contains a static initializer -- static ios_base::Init __ioinit; --
but that we only need istream and ostream here).
I preprocessed time_hash_map.cc using both libstdc++ and libc++, with and
without an #include of <istream> and <ostream>, and compared the number of
lines in the resulting file:
libc++:
37893 time_hash_map-time_hash_map.orig.libc++.E
55896 time_hash_map-time_hash_map.ios.libc++.E
libstdc++:
60657 time_hash_map-time_hash_map.orig.stdc++.E
60657 time_hash_map-time_hash_map.ios.stdc++.E
So avoiding <istream> doesn't actually win *anything* on libstdc++, because
it's already been pulled in by <iterator>. It's still a significant win on
libc++, though.
Original comment by nelh...@nelhage.com
on 3 Dec 2011 at 4:14
Great (and thanks for the numbers!) I'll get such a change into svn shortly.
Original comment by csilv...@gmail.com
on 5 Dec 2011 at 5:39
OK, committed to SVN.
Original comment by csilv...@gmail.com
on 7 Dec 2011 at 7:56
This is now in sparsehash 1.12, just released.
Original comment by csilv...@gmail.com
on 21 Dec 2011 at 5:27
Original issue reported on code.google.com by
nelh...@nelhage.com
on 2 Dec 2011 at 11:24Attachments: