1 /* Frobby: Software for monomial ideal computations.
2 Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see http://www.gnu.org/licenses/.
16 */
17 #include "stdinc.h"
18 #include "FrobbyStringStream.h"
19
20 #include <algorithm>
21 #include <exception>
22
23 // This is a replacement for stringstream, which may seem weird since
24 // stringstream should work perfectly fine for any purpose where
25 // FrobbyStringStream could be used. Unfortunately this is not the
26 // case.
27 //
28 // The sad truth is that stringstream is unusable due to its behavior
29 // when running out of memory - it just stops what it is doing and
30 // then returns without propagating the bad_alloc exception. Setting
31 // exception flags with the exception() method does not change this
32 // behavior. This is for GCC v. 3.4.4 and on GCC 4.1.2 I have tested
33 // that at least without setting exception() it fails silently, though
34 // not whether that can be changed by using exception().
35 //
36 // The advantage of FrobbyStringStream is that it does not try to be
37 // clever in any way, and so it avoids these issues.
38
operator <<(char character)39 FrobbyStringStream& FrobbyStringStream::operator<<(char character) {
40 _str += character;
41 return *this;
42 }
43
operator <<(unsigned long long integer)44 FrobbyStringStream& FrobbyStringStream::operator<<(unsigned long long integer) {
45 appendIntegerToString(_str, integer);
46 return *this;
47 }
48
operator <<(unsigned long integer)49 FrobbyStringStream& FrobbyStringStream::operator<<(unsigned long integer) {
50 appendIntegerToString(_str, integer);
51 return *this;
52 }
53
operator <<(unsigned int integer)54 FrobbyStringStream& FrobbyStringStream::operator<<(unsigned int integer) {
55 appendIntegerToString(_str, integer);
56 return *this;
57 }
58
operator <<(const mpz_class & integer)59 FrobbyStringStream& FrobbyStringStream::operator<<(const mpz_class& integer) {
60 appendIntegerToString(_str, integer);
61 return *this;
62 }
63
operator <<(const string & text)64 FrobbyStringStream& FrobbyStringStream::operator<<(const string& text) {
65 _str += text;
66 return *this;
67 }
68
operator <<(const char * text)69 FrobbyStringStream& FrobbyStringStream::operator<<(const char* text) {
70 _str += text;
71 return *this;
72 }
73
str()74 string& FrobbyStringStream::str() {
75 return _str;
76 }
77
str() const78 const string& FrobbyStringStream::str() const {
79 return _str;
80 }
81
operator const string&() const82 FrobbyStringStream::operator const string&() const {
83 return _str;
84 }
85
appendIntegerToString(string & str,unsigned long integer)86 void FrobbyStringStream::appendIntegerToString(string& str,
87 unsigned long integer) {
88 unsigned long initialLength = str.size();
89
90 // Append string representation of integer with digits in reverse
91 // order.
92 do {
93 unsigned long quotient = integer / 10;
94 unsigned long remainder = integer - quotient * 10; // faster than %
95
96 char digit = static_cast<char>(remainder + '0');
97 str += digit;
98
99 integer = quotient;
100
101 // condition at end so that zero maps to "0" rather than "".
102 } while (integer != 0);
103
104 // Reverse the digits (and only the digits) to get the correct
105 // order.
106 reverse(str.begin() + initialLength, str.end());
107 }
108
appendIntegerToString(string & str,const mpz_class & integer)109 void FrobbyStringStream::appendIntegerToString(string& str,
110 const mpz_class& integer) {
111 str += integer.get_str();
112 }
113
parseInteger(mpz_class & integer,const string & str)114 void FrobbyStringStream::parseInteger(mpz_class& integer, const string& str) {
115 if (integer.set_str(str, 10) != 0)
116 throw NotAnIntegerException
117 ("Argument to FrobbyStringStream::parseInteger not a valid integer.");
118 }
119
NotAnIntegerException(const string & str)120 FrobbyStringStream::NotAnIntegerException::NotAnIntegerException
121 (const string& str):
122 runtime_error(str) {
123 }
124