Browse Source

ENH: Added istream and ostream operators for stl string when using old streams that do not provide them.

Brad King 20 years ago
parent
commit
098c33c4da

+ 30 - 1
Source/kwsys/CMakeLists.txt

@@ -175,6 +175,21 @@ ELSE(KWSYS_IOS_USE_SSTREAM)
   ENDIF(KWSYS_IOS_USE_STRSTREAM_H)
 ENDIF(KWSYS_IOS_USE_SSTREAM)
 
+IF(KWSYS_IOS_USE_ANSI)
+  # ANSI streams always have string operators.
+  SET(KWSYS_STL_STRING_HAVE_OSTREAM 1)
+  SET(KWSYS_STL_STRING_HAVE_ISTREAM 1)
+ELSE(KWSYS_IOS_USE_ANSI)
+  # There may not be string operators for old streams.
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES
+    -DKWSYS_STL_HAVE_STD=${KWSYS_STL_HAVE_STD})
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_OSTREAM
+    "Checking whether stl string has ostream operator<<" DIRECT)
+  KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_STRING_HAVE_ISTREAM
+    "Checking whether stl string has istream operator>>" DIRECT)
+  SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+ENDIF(KWSYS_IOS_USE_ANSI)
+
 IF(UNIX)
   KWSYS_PLATFORM_CXX_TEST(KWSYS_STAT_HAS_ST_MTIM
     "Checking whether struct stat has st_mtim member" DIRECT)
@@ -210,11 +225,25 @@ INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
 #-----------------------------------------------------------------------------
 # Create STL header wrappers to block warnings in the STL headers and
 # give standard names by which they may be included.
+SET(KWSYS_STL_HEADER_EXTRA_string 1)
 FOREACH(header algorithm deque iterator list map numeric queue set stack string
                utility vector)
   # Configure the header wrapper.
   SET(KWSYS_STL_HEADER "${header}")
-  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.h.in
+  IF(KWSYS_STL_HEADER_EXTRA_${header})
+    SET(KWSYS_STL_HEADER_EXTRA
+      "#define ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n# include <${KWSYS_NAMESPACE}/stl/${header}.hxx>\n#undef ${KWSYS_NAMESPACE}_stl_${header}_including_hxx\n")
+    CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl_${header}.hxx.in
+                   ${KWSYS_HEADER_DIR}/stl/${header}.hxx
+                   @ONLY IMMEDIATE)
+    IF(KWSYS_HEADER_INSTALL_DIR)
+      INSTALL_FILES(${KWSYS_HEADER_INSTALL_DIR}/${KWSYS_NAMESPACE}/stl
+        FILES ${KWSYS_HEADER_DIR}/stl/${header}.hxx)
+    ENDIF(KWSYS_HEADER_INSTALL_DIR)
+  ELSE(KWSYS_STL_HEADER_EXTRA_${header})
+    SET(KWSYS_STL_HEADER_EXTRA "")
+  ENDIF(KWSYS_STL_HEADER_EXTRA_${header})
+  CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsys_stl.hxx.in
                  ${KWSYS_HEADER_DIR}/stl/${header}
                  @ONLY IMMEDIATE)
 

+ 6 - 0
Source/kwsys/Configure.hxx.in

@@ -35,6 +35,12 @@
 /* Whether STL is in std namespace.  */
 #define @KWSYS_NAMESPACE@_STL_HAVE_STD @KWSYS_STL_HAVE_STD@
 
+/* Whether the STL string has operator<< for ostream.  */
+#define @KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM @KWSYS_STL_STRING_HAVE_OSTREAM@
+
+/* Whether the STL string has operator>> for istream.  */
+#define @KWSYS_NAMESPACE@_STL_STRING_HAVE_ISTREAM @KWSYS_STL_STRING_HAVE_ISTREAM@
+
 /* Define the stl namespace macro.  */
 #if @KWSYS_NAMESPACE@_STL_HAVE_STD
 # define @KWSYS_NAMESPACE@_stl std

+ 1 - 1
Source/kwsys/kwsysPlatformCxxTests.cmake

@@ -4,7 +4,7 @@ MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
     TRY_COMPILE(${var}_COMPILED
       ${CMAKE_CURRENT_BINARY_DIR}
       ${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformCxxTests.cxx
-      COMPILE_DEFINITIONS -DTEST_${var}
+      COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_CXX_TEST_DEFINES}
       OUTPUT_VARIABLE OUTPUT)
     IF(${var}_COMPILED)
       WRITE_FILE(${CMAKE_CURRENT_BINARY_DIR}/CMakeOutput.log

+ 24 - 0
Source/kwsys/kwsysPlatformCxxTests.cxx

@@ -30,6 +30,30 @@ int main() { return 0; }
 int main() { return 0; }
 #endif
 
+#ifdef TEST_KWSYS_STL_STRING_HAVE_OSTREAM
+# if KWSYS_STL_HAVE_STD
+#  define kwsys_stl std
+# else
+#  define kwsys_stl
+# endif
+# include <iostream.h>
+# include <string>
+void f(ostream& os, const kwsys_stl::string& s) { os << s; }
+int main() { return 0; }
+#endif
+
+#ifdef TEST_KWSYS_STL_STRING_HAVE_ISTREAM
+# if KWSYS_STL_HAVE_STD
+#  define kwsys_stl std
+# else
+#  define kwsys_stl
+# endif
+# include <iostream.h>
+# include <string>
+void f(istream& is, kwsys_stl::string& s) { is >> s; }
+int main() { return 0; }
+#endif
+
 #ifdef TEST_KWSYS_STAT_HAS_ST_MTIM
 #include <sys/types.h>
 #include <sys/stat.h>

+ 1 - 0
Source/kwsys/kwsys_stl.h.in → Source/kwsys/kwsys_stl.hxx.in

@@ -28,4 +28,5 @@
 # pragma warning(pop)
 #endif
 
+@KWSYS_STL_HEADER_EXTRA@
 #endif

+ 92 - 0
Source/kwsys/kwsys_stl_string.hxx.in

@@ -0,0 +1,92 @@
+/*=========================================================================
+
+  Program:   KWSys - Kitware System Library
+  Module:    $RCSfile$
+
+  Copyright (c) Kitware, Inc., Insight Consortium.  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+// This header is extra code for <@KWSYS_NAMESPACE@/stl/string>.
+#if !defined(@KWSYS_NAMESPACE@_stl_string_including_hxx)
+# error "The header <@KWSYS_NAMESPACE@/stl/string.hxx> may be included only by <@KWSYS_NAMESPACE@/stl/string>."
+#endif
+
+// Provide the istream operator for the stl string if it is not
+// provided by the system or another copy of kwsys.  Allow user code
+// to block this definition by defining the macro
+// @KWSYS_NAMESPACE@_STL_STRING_NO_ISTREAM
+// to avoid conflicts with other libraries.
+#if !@KWSYS_NAMESPACE@_STL_STRING_HAVE_ISTREAM && \
+    !defined(@KWSYS_NAMESPACE@_STL_STRING_NO_ISTREAM) && \
+    !defined(KWSYS_STL_STRING_ISTREAM_DEFINED)
+# define KWSYS_STL_STRING_ISTREAM_DEFINED
+# include <ctype.h> // isspace
+# include <@KWSYS_NAMESPACE@/ios/iostream>
+inline @KWSYS_NAMESPACE@_ios::istream&
+operator>>(@KWSYS_NAMESPACE@_ios::istream& is,
+           @KWSYS_NAMESPACE@_stl::string& s)
+{
+  // Keep track of the resulting state.
+  int state = @KWSYS_NAMESPACE@_ios::ios::goodbit;
+
+  // Save the width setting and set it back to zero.
+  size_t n = static_cast<size_t>(is.width(0));
+
+  // Clear any old contents of the output string.
+  s.erase();
+
+  // Skip leading whitespace.
+  is.eatwhite();
+  istream& okay = is;
+
+  if(okay)
+    {
+    // Select a maximum possible length.
+    if(n == 0 || n >= s.max_size())
+      {
+      n = s.max_size();
+      }
+
+    // Read until a space is found or the maximum length is reached.
+    bool success = false;
+    for(int c = is.peek(); (--n > 0 && c != EOF && !isspace(c)); c = is.peek())
+      {
+      s += static_cast<char>(c);
+      success = true;
+      is.ignore();
+      }
+
+    // Set flags for resulting state.
+    if(is.peek() == EOF) { state |= @KWSYS_NAMESPACE@_ios::ios::eofbit; }
+    if(success) { state |= @KWSYS_NAMESPACE@_ios::ios::failbit; }
+    }
+
+  // Set the final result state.
+  is.clear(state);
+  return is;
+}
+#endif
+
+// Provide the ostream operator for the stl string if it is not
+// provided by the system or another copy of kwsys.  Allow user code
+// to block this definition by defining the macro
+// @KWSYS_NAMESPACE@_STL_STRING_NO_OSTREAM
+// to avoid conflicts with other libraries.
+#if !@KWSYS_NAMESPACE@_STL_STRING_HAVE_OSTREAM && \
+    !defined(@KWSYS_NAMESPACE@_STL_STRING_NO_OSTREAM) && \
+    !defined(KWSYS_STL_STRING_OSTREAM_DEFINED)
+# define KWSYS_STL_STRING_OSTREAM_DEFINED
+# include <@KWSYS_NAMESPACE@/ios/iostream>
+inline @KWSYS_NAMESPACE@_ios::ostream&
+operator<<(@KWSYS_NAMESPACE@_ios::ostream& os,
+           @KWSYS_NAMESPACE@_stl::string const& s)
+{
+  return os << s.c_str();
+}
+#endif