stream: Add support for 64-bit integers
diff mbox series

Message ID 20190402040750.304-1-rosenp@gmail.com
State New
Headers show
Series
  • stream: Add support for 64-bit integers
Related show

Commit Message

Rosen Penev April 2, 2019, 4:07 a.m. UTC
Many programs like gptfdisk or powertop try to use 64-bit integers with
streams. This adds support for them.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 include/istream         | 21 ++++++++++++++++
 include/istream_helpers | 55 +++++++++++++++++++++++++++++++++++++++++
 include/ostream         | 20 +++++++++++++++
 tests/sstreamtest.cpp   | 10 +++++++-
 4 files changed, 105 insertions(+), 1 deletion(-)

Comments

Bernhard Reutner-Fischer April 4, 2019, 3:02 p.m. UTC | #1
On Tue, 2 Apr 2019 at 06:07, Rosen Penev <rosenp@gmail.com> wrote:
>
> Many programs like gptfdisk or powertop try to use 64-bit integers with
> streams. This adds support for them.

I had to tweak the test a bit and also had to adjust the expected test-output.
make check
resp, for a diff:
make check V=1

Applied with these minor edits, thanks!

Patch
diff mbox series

diff --git a/include/istream b/include/istream
index 850ac30..afcaa5b 100644
--- a/include/istream
+++ b/include/istream
@@ -72,6 +72,11 @@  namespace std{
 		basic_istream<charT,traits>& operator>>(void*& p);
 		basic_istream<charT,traits>& operator>>(basic_streambuf<char_type,traits>* sb);
 
+#ifndef __STRICT_ANSI__
+		basic_istream<charT,traits>& operator>>(long long& n);
+		basic_istream<charT,traits>& operator>>(unsigned long long& n);
+#endif
+
 #ifdef __UCLIBCXX_HAS_FLOATS__
 		basic_istream<charT,traits>& operator>>(float& f);
 		basic_istream<charT,traits>& operator>>(double& f);
@@ -450,6 +455,22 @@  namespace std{
 		return *this;
 	}
 
+#ifndef __STRICT_ANSI__
+	template <class charT, class traits> _UCXXEXPORT basic_istream<charT,traits>&
+		basic_istream<charT,traits>::operator>>(long long& n)
+	{
+		sentry(*this);
+		__istream_readin<traits, charT, long long>::readin(*this, n);
+		return *this;
+	}
+	template <class charT, class traits> _UCXXEXPORT basic_istream<charT,traits>&
+		basic_istream<charT,traits>::operator>>(unsigned long long& n)
+	{
+		sentry(*this);
+		__istream_readin<traits, charT, unsigned long long>::readin(*this, n);
+		return *this;
+	}
+#endif
 #ifdef __UCLIBCXX_HAS_FLOATS__
 	template <class charT, class traits> _UCXXEXPORT basic_istream<charT,traits>&
 		basic_istream<charT,traits>::operator>>(float& n)
diff --git a/include/istream_helpers b/include/istream_helpers
index 588df7f..d87e0c7 100644
--- a/include/istream_helpers
+++ b/include/istream_helpers
@@ -301,6 +301,61 @@  namespace std{
 	};
 
 
+#ifndef __STRICT_ANSI__
+	template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long long>{
+	public:
+		inline static void readin(basic_istream<char, traits >& stream, long long & var)
+		{
+			basic_string<char, traits > temp;
+
+			if(stream.flags() & ios_base::dec){
+				temp = _readTokenDecimal( stream);
+				sscanf(temp.c_str(), "%lld", &var );
+			}else{
+				temp = _readToken( stream);
+				if( stream.flags() & ios_base::oct){
+					sscanf(temp.c_str(), "%llo", (unsigned long long *)&var );
+				}else if(stream.flags() & ios_base::hex){
+					if(stream.flags() & ios_base::uppercase){
+						scanf(temp.c_str(), "%llX", (unsigned long long *)&var );
+					}else{
+						sscanf(temp.c_str(), "%llx", (unsigned long long *)&var);
+					}
+				}else{
+					sscanf(temp.c_str(), "%lli", (&var) );
+				}
+			}
+		}
+	};
+
+
+	template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long long>{
+	public:
+		inline static void readin(basic_istream<char, traits >& stream, unsigned long long & var)
+		{
+			basic_string<char, traits > temp;
+
+			if(stream.flags() & ios_base::dec){
+				temp = _readTokenDecimal( stream);
+				sscanf(temp.c_str(), "%llu", &var );
+			}else{
+				temp = _readToken( stream);
+				if( stream.flags() & ios_base::oct){
+					sscanf(temp.c_str(), "%llo", &var );
+				}else if(stream.flags() & ios_base::hex){
+					if(stream.flags() & ios_base::uppercase){
+						scanf(temp.c_str(), "%llX", &var );
+					}else{
+						sscanf(temp.c_str(), "%llx", &var);
+					}
+				}else{
+					sscanf(temp.c_str(), "%lli", (long long *)(&var) );
+				}
+			}
+		}
+	};
+#endif
+
 #ifdef __UCLIBCXX_HAS_FLOATS__
 
 	template <class traits> class _UCXXEXPORT __istream_readin<traits, char, float>{
diff --git a/include/ostream b/include/ostream
index b112e94..289514c 100644
--- a/include/ostream
+++ b/include/ostream
@@ -85,6 +85,10 @@  namespace std {
 		basic_ostream<charT,traits>& operator<<(long double f);
 		basic_ostream<charT,traits>& operator<<(void* p);
 		basic_ostream<charT,traits>& operator<<(basic_streambuf<char_type,traits>* sb);
+#ifndef __STRICT_ANSI__
+		basic_ostream<charT,traits>& operator<<(long long n);
+		basic_ostream<charT,traits>& operator<<(unsigned long long n);
+#endif
 
 		_UCXXEXPORT basic_ostream<charT,traits>& put(char_type c){
 			if(basic_ostream<charT,traits>::traits_type::eq_int_type(
@@ -217,6 +221,22 @@  namespace std {
 		return *this;
 	}
 
+#ifndef __STRICT_ANSI__
+	template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(long long n)
+	{
+		sentry s(*this);
+		__ostream_printout<traits, charT, long long >::printout(*this, n);
+		return *this;
+	}
+
+	template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(unsigned long long n)
+	{
+		sentry s(*this);
+		__ostream_printout<traits, charT, unsigned long long >::printout(*this, n);
+		return *this;
+	}
+#endif
+
 	template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(float f){
 		sentry s(*this);
 		__ostream_printout<traits, charT, double >::printout(*this, f);
diff --git a/tests/sstreamtest.cpp b/tests/sstreamtest.cpp
index df3d521..7543ee3 100644
--- a/tests/sstreamtest.cpp
+++ b/tests/sstreamtest.cpp
@@ -9,6 +9,9 @@  int main(){
 	int i;
 	std::string s;
 	char c;
+#ifndef __STRICT_ANSI__
+	long long ll;
+#endif
 
 	a << "Starting testing ";
 	a << 2 ;
@@ -28,9 +31,14 @@  int main(){
 
 
 
+#ifndef __STRICT_ANSI__
+	a.str("55 2.35 5 Test");
+	a >> ll >> f >> i >> s;
+	std::cout << "ll (should be 55): " << ll << std::endl;
+#else
 	a.str("2.35 5 Test");
-
 	a >> f >> i >> s;
+#endif
 
 	std::cout << "f (should be 2.35): " << f << std::endl;
 	std::cout << "i (should be 5): " << i << std::endl;