This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Allow fstream ctor to take std::string arguments


This is just for the record; I won't propose applying this until post-3.0
even though it does nothing without the user's input.  At one point I was
thinking of proposing this for 3.0, and for 3.1 leaving the extension /on/
by default, but that's prolly not smart now.


Friends, colleagues, and complete strangers often complain to me and
to the world in general (newsgroups) that you can't pass a string to an
fstream ctor; you have to use a char* to pass the filename.  If you /were/
using a string to hold the filename -- as you should -- then you have to
use .c_str() to "drop down into C" briefly, as it were.

There are good reasons for not requiring std::string to be an argument and
they probably don't need to be repeated here.  But comp.std.c++ has been
holding a wishlist-fest for the last few weeks, and some of the articles
I've moderated mention this "failing" of the I/O library, and hopes that
it can be "corrected" in C++0x.

Of course, we all know that it's good to see an actual implementation
of something, and how it gets used in the community, before adding that
something to the standard.

So, anyhow, I did this.  A basic_string can be passed to the ctor as well
as open().  The string can be templated on a different character type than
the fstream.  All of them are, by default, dropped by the preprocessor,
unless the user defines a hook before inclusion:

    #define _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
    #include <fstream>

which is cheesy but safe.  Other methods solicited.

Including basic_string.h is probably quite a hit for parsing time; I didn't
measure.  We could get away with including stringfwd.h (something which I
would like to see added to the standard) instead, if we were willing to move
the function bodies elsewhere (otherwise we need to see the decl of c_str()).

Built, tested, it works.  I haven't run this past any of the language
experts I usually consult before posting :-) so it could probably stand
some improvement.  Here was my simple test:

    #include <iostream>
    #define _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
    #include <fstream>
    
    int main()
    {
        std::string      str = "c++config";
        std::ifstream    file (str);
    
        file >> str;
        // should print the initial "//" of c++config
        std::cout << str << std::endl;
    }


Phil



Index: std_fstream.h
===================================================================
RCS file: /home/pme/Repositories/GCC/gcc/libstdc++-v3/include/bits/std_fstream.h,v
retrieving revision 1.10
diff -u -3 -p -r1.10 std_fstream.h
--- std_fstream.h	2001/05/24 23:09:53	1.10
+++ std_fstream.h	2001/05/30 01:20:46
@@ -41,6 +41,9 @@
 #include <bits/basic_file.h>
 #include <bits/std_locale.h>	// For codecvt
 #include <bits/c++threads.h>	// For __mutext_type
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+#include <bits/basic_string.h>
+#endif
 
 namespace std 
 {
@@ -260,7 +263,19 @@ namespace std 
 	this->init(&_M_filebuf); 
 	this->open(__s, __mode); 
       }
-    
+
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        explicit 
+        basic_ifstream(const basic_string<_StringCharT>& __s,
+	               ios_base::openmode __mode = ios_base::in)
+        : __istream_type(NULL), _M_filebuf()
+        { 
+          this->init(&_M_filebuf); 
+          this->open(__s.c_str(), __mode); 
+        }
+#endif
+
       ~basic_ifstream()
       { }
 
@@ -279,6 +294,17 @@ namespace std 
 	  this->setstate(ios_base::failbit); 
       }
 
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        void 
+        open(const basic_string<_StringCharT>& __s,
+	     ios_base::openmode __mode = ios_base::in)
+        { 
+          if (_M_filebuf.open(__s.c_str(), __mode | ios_base::in) == NULL)
+            this->setstate(ios_base::failbit); 
+        }
+#endif
+
       void 
       close(void)
       { 
@@ -322,6 +348,18 @@ namespace std 
 	this->open(__s, __mode); 
       }
 
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        explicit 
+        basic_ofstream(const basic_string<_StringCharT>& __s,
+	              ios_base::openmode __mode = ios_base::out|ios_base::trunc)
+        : __ostream_type(NULL), _M_filebuf()
+        { 
+          this->init(&_M_filebuf); 
+          this->open(__s.c_str(), __mode); 
+        }
+#endif
+
       ~basic_ofstream()
       { }
 
@@ -341,6 +379,17 @@ namespace std 
 	  this->setstate(ios_base::failbit); 
       }
 
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        void 
+        open(const basic_string<_StringCharT>& __s,
+	     ios_base::openmode __mode = ios_base::out | ios_base::trunc)
+        { 
+          if (!_M_filebuf.open(__s.c_str(), __mode | ios_base::out))
+            this->setstate(ios_base::failbit); 
+        }
+#endif
+
       void 
       close(void)
       { 
@@ -385,6 +434,18 @@ namespace std 
 	this->open(__s, __mode); 
       }
  
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        explicit 
+        basic_fstream(const basic_string<_StringCharT>& __s,
+	              ios_base::openmode __mode = ios_base::in | ios_base::out)
+        : __iostream_type(NULL), _M_filebuf()
+        { 
+          this->init(&_M_filebuf); 
+          this->open(__s.c_str(), __mode); 
+        }
+#endif
+
       ~basic_fstream()
       { }
     
@@ -403,6 +464,17 @@ namespace std 
 	if (!_M_filebuf.open(__s, __mode))
 	  setstate(ios_base::failbit); 
       }
+
+#ifdef _GLIBCPP_STRINGS_IN_IOSTREAM_CTORS
+      template <typename _StringCharT>
+        void 
+        open(const basic_string<_StringCharT>& __s,
+	     ios_base::openmode __mode = ios_base::in | ios_base::out)
+        { 
+          if (!_M_filebuf.open(__s.c_str(), __mode))
+            this->setstate(ios_base::failbit); 
+        }
+#endif
 
       void 
       close(void)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]