Skip to content

Commit

Permalink
Introduce ctl::to_string()
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Jul 1, 2024
1 parent acbabed commit e627bfa
Show file tree
Hide file tree
Showing 11 changed files with 432 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,10 @@ include third_party/ncurses/BUILD.mk # │
include third_party/readline/BUILD.mk #
include third_party/libunwind/BUILD.mk # |
include third_party/libcxxabi/BUILD.mk # |
include third_party/double-conversion/BUILD.mk #
include ctl/BUILD.mk #
include third_party/libcxx/BUILD.mk #
include third_party/openmp/BUILD.mk #
include third_party/double-conversion/BUILD.mk #
include third_party/pcre/BUILD.mk #
include third_party/less/BUILD.mk #
include net/https/BUILD.mk #
Expand Down
1 change: 1 addition & 0 deletions ctl/BUILD.mk
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ CTL_A_DIRECTDEPS = \
LIBC_NEXGEN32E \
LIBC_STDIO \
LIBC_STR \
THIRD_PARTY_DOUBLECONVERSION \
THIRD_PARTY_GDTOA \
THIRD_PARTY_LIBCXXABI \
THIRD_PARTY_LIBUNWIND \
Expand Down
35 changes: 35 additions & 0 deletions ctl/dubble.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// -*- mode:c++; indent-tabs-mode:nil; c-basic-offset:4; coding:utf-8 -*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
//
// Copyright 2024 Justine Alexandra Roberts Tunney
//
// Permission to use, copy, modify, and/or distribute this software for
// any purpose with or without fee is hereby granted, provided that the
// above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
// AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
// DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
// PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#include "dubble.h"

namespace ctl {

const double_conversion::DoubleToStringConverter kDoubleToPrintfG(
double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN |
double_conversion::DoubleToStringConverter::NO_TRAILING_ZERO,
"inf",
"nan",
'e',
-6,
10, // let 32-bit ints be represented without exponent
6,
0,
0);

} // namespace ctl
13 changes: 13 additions & 0 deletions ctl/dubble.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// -*-mode:c++;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8-*-
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
#ifndef COSMOPOLITAN_CTL_DUBBLE_H_
#define COSMOPOLITAN_CTL_DUBBLE_H_
#include "third_party/double-conversion/double-to-string.h"

namespace ctl {

extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG;

} // namespace ctl

#endif // COSMOPOLITAN_CTL_DUBBLE_H_
73 changes: 63 additions & 10 deletions ctl/ostream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
// PERFORMANCE OF THIS SOFTWARE.

#include "ostream.h"
#include "dubble.h"
#include "libc/fmt/itoa.h"
#include "libc/stdio/stdio.h"
#include "string_view.h"

namespace ctl {

extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG;

ostream cout(stdout);
ostream cerr(stderr);

Expand Down Expand Up @@ -50,7 +54,7 @@ ostream&
ostream::operator<<(const char* str)
{
if (good() && str)
if (fprintf(file_, "%s", str) < 0)
if (fputs(str, file_) < 0)
setstate(badbit);
return *this;
}
Expand All @@ -67,35 +71,84 @@ ostream::operator<<(char c)
ostream&
ostream::operator<<(int n)
{
if (good())
if (fprintf(file_, "%d", n) < 0)
if (good()) {
char buf[12];
FormatInt32(buf, n);
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(unsigned n)
{
if (good()) {
char buf[12];
FormatUint32(buf, n);
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(long n)
{
if (good())
if (fprintf(file_, "%ld", n) < 0)
if (good()) {
char buf[21];
FormatInt64(buf, n);
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(unsigned long n)
{
if (good()) {
char buf[21];
FormatUint64(buf, n);
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(float f)
{
if (good()) {
char buf[128];
double_conversion::StringBuilder b(buf, sizeof(buf));
kDoubleToPrintfG.ToShortestSingle(f, &b);
b.Finalize();
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(double d)
{
if (good())
if (fprintf(file_, "%f", d) < 0)
if (good()) {
char buf[128];
double_conversion::StringBuilder b(buf, sizeof(buf));
kDoubleToPrintfG.ToShortest(d, &b);
b.Finalize();
if (fputs(buf, file_) < 0)
setstate(badbit);
}
return *this;
}

ostream&
ostream::operator<<(const string_view& s)
{
if (good())
if (fprintf(file_, "%.*s", (int)s.size(), s.data()) < 0)
if (good() && s.size())
if (!fwrite(s.data(), s.size(), 1, file_))
setstate(badbit);
return *this;
}
Expand All @@ -106,7 +159,7 @@ ostream::operator<<(bool b)
if (good()) {
const char* value =
(flags() & boolalpha) ? (b ? "true" : "false") : (b ? "1" : "0");
if (fprintf(file_, "%s", value) < 0)
if (fputs(value, file_) < 0)
setstate(badbit);
}
return *this;
Expand Down
5 changes: 4 additions & 1 deletion ctl/ostream.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@ class ostream : public ios
virtual ~ostream();

ostream& operator<<(const char*);
ostream& operator<<(bool);
ostream& operator<<(char);
ostream& operator<<(int);
ostream& operator<<(unsigned);
ostream& operator<<(long);
ostream& operator<<(unsigned long);
ostream& operator<<(float);
ostream& operator<<(double);
ostream& operator<<(const ctl::string_view&);
ostream& operator<<(bool);
ostream& operator<<(ostream& (*)(ostream&));

ostream& put(char);
Expand Down
58 changes: 34 additions & 24 deletions ctl/ostringstream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,30 @@
// PERFORMANCE OF THIS SOFTWARE.

#include "ostringstream.h"
#include "dubble.h"
#include "libc/fmt/itoa.h"
#include "libc/stdio/stdio.h"

namespace ctl {

extern const double_conversion::DoubleToStringConverter kDoubleToPrintfG;

ostringstream::ostringstream() : buffer_(), write_pos_(0)
{
}

ostringstream::ostringstream(const ctl::string_view& str)
ostringstream::ostringstream(const string_view& str)
: buffer_(str), write_pos_(0)
{
}

ctl::string
string
ostringstream::str() const
{
return buffer_;
}

void
ostringstream::str(const ctl::string& s)
ostringstream::str(const string& s)
{
buffer_ = s;
write_pos_ = 0;
Expand All @@ -65,7 +67,7 @@ ostringstream::operator<<(char c)
}

ostringstream&
ostringstream::operator<<(const ctl::string_view& s)
ostringstream::operator<<(const string_view& s)
{
if (good()) {
if (write_pos_ + s.size() <= buffer_.size()) {
Expand All @@ -82,46 +84,52 @@ ostringstream::operator<<(const ctl::string_view& s)
ostringstream&
ostringstream::operator<<(int n)
{
char temp[12];
if (good())
*this << ctl::string_view(temp, FormatInt32(temp, n) - temp);
if (good()) {
char buf[12];
*this << string_view(buf, FormatInt32(buf, n) - buf);
}
return *this;
}

ostringstream&
ostringstream::operator<<(unsigned int n)
ostringstream::operator<<(unsigned n)
{
char temp[12];
if (good())
*this << ctl::string_view(temp, FormatUint32(temp, n) - temp);
if (good()) {
char buf[12];
*this << string_view(buf, FormatUint32(buf, n) - buf);
}
return *this;
}

ostringstream&
ostringstream::operator<<(long n)
{
char temp[21];
if (good())
*this << ctl::string_view(temp, FormatInt64(temp, n) - temp);
if (good()) {
char buf[21];
*this << string_view(buf, FormatInt64(buf, n) - buf);
}
return *this;
}

ostringstream&
ostringstream::operator<<(unsigned long n)
{
char temp[21];
if (good())
*this << ctl::string_view(temp, FormatUint64(temp, n) - temp);
if (good()) {
char buf[21];
*this << string_view(buf, FormatUint64(buf, n) - buf);
}
return *this;
}

ostringstream&
ostringstream::operator<<(float f)
{
if (good()) {
char temp[32];
int len = snprintf(temp, sizeof(temp), "%g", f);
*this << ctl::string_view(temp, len);
char buf[128];
double_conversion::StringBuilder b(buf, sizeof(buf));
kDoubleToPrintfG.ToShortestSingle(f, &b);
b.Finalize();
*this << string_view(buf);
}
return *this;
}
Expand All @@ -130,9 +138,11 @@ ostringstream&
ostringstream::operator<<(double d)
{
if (good()) {
char temp[32];
int len = snprintf(temp, sizeof(temp), "%g", d);
*this << ctl::string_view(temp, len);
char buf[128];
double_conversion::StringBuilder b(buf, sizeof(buf));
kDoubleToPrintfG.ToShortest(d, &b);
b.Finalize();
*this << string_view(buf);
}
return *this;
}
Expand Down
Loading

0 comments on commit e627bfa

Please sign in to comment.