diff options
author | Niko Catania <niko@google.com> | 2010-02-04 15:03:01 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-02-04 15:03:01 -0800 |
commit | 80026dde32d301f096ab7d2c19ca6b93fe69ee2a (patch) | |
tree | 661bbbb9e6c9309d6c5356916f5eec1b0820f613 | |
parent | 328cfeefa59a829fd8ae83ff1955c530a25b43ff (diff) | |
parent | f1112427006f4fd9b72cb46acd46ddbbf1e7b741 (diff) | |
download | astl-80026dde32d301f096ab7d2c19ca6b93fe69ee2a.tar.gz |
Merge "Added basic support for the streams flags and iomanip."
-rw-r--r-- | include/iomanip | 82 | ||||
-rw-r--r-- | include/ios_base.h | 96 | ||||
-rw-r--r-- | src/ios_base.cpp | 25 | ||||
-rw-r--r-- | tests/Android.mk | 1 | ||||
-rw-r--r-- | tests/test_iomanip.cpp | 73 |
5 files changed, 274 insertions, 3 deletions
diff --git a/include/iomanip b/include/iomanip new file mode 100644 index 0000000..2602776 --- /dev/null +++ b/include/iomanip @@ -0,0 +1,82 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2010 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ANDROID_ASTL_IOMANIP__ +#define ANDROID_ASTL_IOMANIP__ + +#include <ostream> + +// iomanips are structures used to manipulate streams. There are 3 +// parts to a manip: +// - a struct to hold the parameters of the manip. +// - a function in the std namespace to generate the above structure. +// - a stream operator that takes the structure as second argument and +// apply the manip using the params in the structure. +// +// This allows something like that : cout << setprecision(10); + +namespace android { +// Structures passed to the streams to set various aspect of it. +struct SetBase { int base; }; +struct SetPrecision { int precision; }; +} + +namespace std { + +// Sent to a stream, calls 'precision(size_type)' on the instance. +inline android::SetPrecision setprecision(int precision) { + android::SetPrecision params; + params.precision = precision; + return params; +} + +inline ostream& operator<<(ostream& os, android::SetPrecision params) { + os.precision(params.precision); + return os; +} + +// Sent to a stream, set the ios_base::basefield on the instance. +// Sent to a stream, calls 'precision(size_type)' on the instance. +inline android::SetBase setbase(int base) { + android::SetBase params; + params.base = base; + return params; +} + +inline ostream& operator<<(ostream& os, android::SetBase params) { + os.setf(params.base == 8 ? ios_base::oct : + params.base == 10 ? ios_base::dec : + params.base == 16 ? ios_base::hex : + ios_base::fmtflags(0), ios_base::basefield); + return os; +} + +} // namespace std + +#endif diff --git a/include/ios_base.h b/include/ios_base.h index 18b0ef8..2fe6660 100644 --- a/include/ios_base.h +++ b/include/ios_base.h @@ -32,6 +32,32 @@ #include <ios_pos_types.h> +namespace android { +// Flags are used to put the stream is a certain state which affect +// how data is formatted. +enum IosBaseFlags { + ios_baseflags_boolalpha = 1 << 0, + ios_baseflags_dec = 1 << 1, + ios_baseflags_fixed = 1 << 2, + ios_baseflags_hex = 1 << 3, + ios_baseflags_internal = 1 << 4, + ios_baseflags_left = 1 << 5, + ios_baseflags_oct = 1 << 6, + ios_baseflags_right = 1 << 7, + ios_baseflags_scientific = 1 << 8, + ios_baseflags_showbase = 1 << 9, + ios_baseflags_showpoint = 1 << 10, + ios_baseflags_showpos = 1 << 11, + ios_baseflags_skipws = 1 << 12, + ios_baseflags_unitbuf = 1 << 13, + ios_baseflags_uppercase = 1 << 14, + ios_baseflags_adjustfield = ios_baseflags_left | ios_baseflags_right | ios_baseflags_internal, + ios_baseflags_basefield = ios_baseflags_dec | ios_baseflags_oct | ios_baseflags_hex, + ios_baseflags_floatfield = ios_baseflags_scientific | ios_baseflags_fixed, + ios_baseflags_end = 1 << 15 +}; +} // namespace android + namespace std { /** @@ -60,6 +86,70 @@ class ios_base public: virtual ~ios_base(); + typedef int fmtflags; + + // boolalpha: Insert and extract bool type in alphabetic format. + // dec: Convert integer input or generates integer output in + // decimal base. + // fixed: Generate floating-point output in a fixed-point notation. + // hex: Convert integer input or generates integer output in + // hexadecimal base. + // internal: Adds fill characters as the designated interanl point + // in certain generated output, or identical to right + // if no such point is designated. + // left: Adds fill characters on the right (final positions) of + // certain generated output. + // oct: Convert integer input or generates integer output in octal + // base. + // right: Adds fill characters on the left (initial positions) of + // certain generated output. + // scientific: Generates floating point output in scientific notation. + // showbase: Generates a prefix indicating the numeric base of generated + // integer output. + // showpoint: Generate a decimal point character unconditionally in + // generated floating point output. + // showpos: Generate a + sign in non-negative generated numeric output. + // skipws: Skips leading white space before certain input operations. + // unitbuf: Flushes output after each output operation. + // uppercase: Replaces certain lowercase letters with their upppercase + // equivalents in generated output. + static const fmtflags boolalpha = android::ios_baseflags_boolalpha; + static const fmtflags dec = android::ios_baseflags_dec; + static const fmtflags fixed = android::ios_baseflags_fixed; + static const fmtflags hex = android::ios_baseflags_hex; + static const fmtflags internal = android::ios_baseflags_internal; + static const fmtflags left = android::ios_baseflags_left; + static const fmtflags oct = android::ios_baseflags_oct; + static const fmtflags right = android::ios_baseflags_right; + static const fmtflags scientific = android::ios_baseflags_scientific; + static const fmtflags showbase = android::ios_baseflags_showbase; + static const fmtflags showpoint = android::ios_baseflags_showpoint; + static const fmtflags showpos = android::ios_baseflags_showpos; + static const fmtflags skipws = android::ios_baseflags_skipws; + static const fmtflags unitbuf = android::ios_baseflags_unitbuf; + static const fmtflags uppercase = android::ios_baseflags_uppercase; + + static const fmtflags adjustfield = android::ios_baseflags_adjustfield; + static const fmtflags basefield = android::ios_baseflags_basefield; + static const fmtflags floatfield = android::ios_baseflags_floatfield; + + // Set all the flags at once. + // @return the previous value of the format flags + fmtflags flags(fmtflags flags); + + // @return all the flags at once + fmtflags flags() const { return mFlags; } + + // Set flags. + // @return the previous value of the format flags + fmtflags setf(fmtflags flags); + + // Clears 'mask' and set the 'flags' & 'mask'. + // @return the previous value of the format flags + fmtflags setf(fmtflags flags, fmtflags mask); + + // Clears 'mask'. + void unsetf(fmtflags mask); /** * @return The precision (number of digits after the decimal @@ -86,8 +176,9 @@ class ios_base streamsize width(streamsize width); // Helper class to initialize the standard streams. Its - // construction ensures the initialization of the stdio - // streams (cout, cerr,...) declared in iostream. + // construction ensures the initialization of the stdio streams + // (cout, cerr,...) declared in iostream. These wrap the standard + // C streams declared in <cstdio>. // The destruction of the last instance of this class will flush // the streams. class Init { @@ -102,6 +193,7 @@ class ios_base }; private: + fmtflags mFlags; streamsize mPrecision; streamsize mWidth; }; diff --git a/src/ios_base.cpp b/src/ios_base.cpp index e933243..04341e7 100644 --- a/src/ios_base.cpp +++ b/src/ios_base.cpp @@ -45,10 +45,33 @@ bool ios_base::Init::sDone = false; // Implementation of the ios_base, common stuff for all the streams. ios_base::ios_base() - : mPrecision(6), mWidth(0) {} + : mFlags(skipws | dec), mPrecision(6), mWidth(0) {} ios_base::~ios_base() {} +ios_base::fmtflags ios_base::flags(fmtflags flags) { + fmtflags prev = mFlags; + mFlags = flags; + return prev; +} + +ios_base::fmtflags ios_base::setf(fmtflags flags) { + fmtflags prev = mFlags; + mFlags = flags; + return prev; +} + +ios_base::fmtflags ios_base::setf(fmtflags flags, fmtflags mask) { + fmtflags prev = mFlags; + mFlags &= ~mask; + mFlags |= (flags & mask); + return prev; +} + +void ios_base::unsetf(fmtflags mask) { + mFlags &= ~mask; +} + streamsize ios_base::precision(streamsize precision) { const streamsize prev = mPrecision; if (precision >= 0) { // Not sure what a negative precision would mean. diff --git a/tests/Android.mk b/tests/Android.mk index d46ba81..1418c3f 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -65,6 +65,7 @@ sources := \ test_char_traits.cpp \ test_functional.cpp \ test_ios_base.cpp \ + test_iomanip.cpp \ test_ios_pos_types.cpp \ test_iostream.cpp \ test_iterator.cpp \ diff --git a/tests/test_iomanip.cpp b/tests/test_iomanip.cpp new file mode 100644 index 0000000..b8166cc --- /dev/null +++ b/tests/test_iomanip.cpp @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2010 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "../include/iomanip" +#ifndef ANDROID_ASTL_IOMANIP__ +#error "Wrong header included!!" +#endif +#include "common.h" + +namespace android { +using std::ios_base; + +class os: public std::ostream { + public: +}; + +bool testSetPrecision() { + os s; + EXPECT_TRUE(s.precision() == 6); + s << std::setprecision(20); + EXPECT_TRUE(s.precision() == 20); + return true; +} + +bool testSetBase() { + typedef std::ios_base::fmtflags fmtflags; + os s; + + EXPECT_TRUE(s.flags() == (ios_base::dec | ios_base::skipws)); + s << std::setbase(8); + EXPECT_TRUE(s.flags() == (ios_base::oct | ios_base::skipws)); + s << std::setbase(10); + EXPECT_TRUE(s.flags() == (ios_base::dec | ios_base::skipws)); + s << std::setbase(16); + EXPECT_TRUE(s.flags() == (ios_base::hex | ios_base::skipws)); + s << std::setbase(35); + EXPECT_TRUE(s.flags() == ( ios_base::skipws)); + return true; +} + +} // namespace android + +int main(int argc, char **argv){ + FAIL_UNLESS(testSetPrecision); + FAIL_UNLESS(testSetBase); + return kPassed; +} |