123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673 |
- //
- // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef BOOST_LOCALE_FORMATTING_HPP_INCLUDED
- #define BOOST_LOCALE_FORMATTING_HPP_INCLUDED
- #include <boost/locale/config.hpp>
- #ifdef BOOST_MSVC
- # pragma warning(push)
- # pragma warning(disable : 4275 4251 4231 4660)
- #endif
- #include <boost/cstdint.hpp>
- #include <boost/locale/time_zone.hpp>
- #include <ostream>
- #include <istream>
- #include <string>
- #include <string.h>
- #include <typeinfo>
- namespace boost {
- namespace locale {
- ///
- /// \brief This namespace holds additional formatting
- /// flags that can be set using ios_info.
- ///
- namespace flags {
- ///
- /// Formatting flags, each one of them has corresponding manipulation
- /// in namespace \a as
- ///
- typedef enum {
- posix = 0,
- number = 1,
- currency = 2,
- percent = 3,
- date = 4,
- time = 5,
- datetime = 6,
- strftime = 7,
- spellout = 8,
- ordinal = 9,
- display_flags_mask = 31,
- currency_default = 0 << 5,
- currency_iso = 1 << 5,
- currency_national = 2 << 5,
- currency_flags_mask = 3 << 5,
- time_default = 0 << 7,
- time_short = 1 << 7,
- time_medium = 2 << 7,
- time_long = 3 << 7,
- time_full = 4 << 7,
- time_flags_mask = 7 << 7,
- date_default = 0 << 10,
- date_short = 1 << 10,
- date_medium = 2 << 10,
- date_long = 3 << 10,
- date_full = 4 << 10,
- date_flags_mask = 7 << 10,
- datetime_flags_mask = date_flags_mask | time_flags_mask
- } display_flags_type;
- ///
- /// Special string patters that can be used
- /// for text formatting
- ///
- typedef enum {
- datetime_pattern, ///< strftime like formatting
- time_zone_id ///< time zone name
- } pattern_type;
- ///
- /// Special integer values that can be used for formatting
- ///
- typedef enum {
- domain_id ///< Domain code - for message formatting
- } value_type;
-
- } // flags
- ///
- /// \brief This class holds an external data - beyond existing fmtflags that std::ios_base holds
- ///
- /// You should almost never create this object directly. Instead, you should access it via ios_info::get(stream_object)
- /// static member function. It automatically creates default formatting data for that stream
- ///
- class BOOST_LOCALE_DECL ios_info {
- public:
- /// \cond INTERNAL
- ios_info();
- ios_info(ios_info const &);
- ios_info const &operator=(ios_info const &);
- ~ios_info();
- /// \endcond
- ///
- /// Get ios_info instance for specific stream object
- ///
- static ios_info &get(std::ios_base &ios);
- ///
- /// Set a flags that define a way for format data like number, spell, currency etc.
- ///
- void display_flags(uint64_t flags);
-
- ///
- /// Set a flags that define how to format currency
- ///
- void currency_flags(uint64_t flags);
-
- ///
- /// Set a flags that define how to format date
- ///
- void date_flags(uint64_t flags);
-
- ///
- /// Set a flags that define how to format time
- ///
- void time_flags(uint64_t flags);
-
- ///
- /// Set a flags that define how to format both date and time
- ///
- void datetime_flags(uint64_t flags);
-
- ///
- /// Set special message domain identification
- ///
- void domain_id(int);
-
- ///
- /// Set time zone for formatting dates and time
- ///
- void time_zone(std::string const &);
-
- ///
- /// Set date/time pattern (strftime like)
- ///
- template<typename CharType>
- void date_time_pattern(std::basic_string<CharType> const &str)
- {
- string_set &s = date_time_pattern_set();
- s.set<CharType>(str.c_str());
- }
- ///
- /// Get a flags that define a way for format data like number, spell, currency etc.
- ///
- uint64_t display_flags() const;
-
- ///
- /// Get a flags that define how to format currency
- ///
- uint64_t currency_flags() const;
-
- ///
- /// Get a flags that define how to format date
- ///
- uint64_t date_flags() const;
-
- ///
- /// Get a flags that define how to format time
- ///
- uint64_t time_flags() const;
- ///
- /// Get a flags that define how to format both date and time
- ///
- uint64_t datetime_flags() const;
-
- ///
- /// Get special message domain identification
- ///
- int domain_id() const;
-
- ///
- /// Get time zone for formatting dates and time
- ///
- std::string time_zone() const;
-
- ///
- /// Get date/time pattern (strftime like)
- ///
- template<typename CharType>
- std::basic_string<CharType> date_time_pattern() const
- {
- string_set const &s = date_time_pattern_set();
- return s.get<CharType>();
- }
-
- /// \cond INTERNAL
- void on_imbue();
- /// \endcond
-
- private:
- class string_set;
- string_set const &date_time_pattern_set() const;
- string_set &date_time_pattern_set();
-
- class BOOST_LOCALE_DECL string_set {
- public:
- string_set();
- ~string_set();
- string_set(string_set const &other);
- string_set const &operator=(string_set const &other);
- void swap(string_set &other);
-
- template<typename Char>
- void set(Char const *s)
- {
- delete [] ptr;
- ptr = 0;
- type=&typeid(Char);
- Char const *end = s;
- while(*end!=0) end++;
- // if ptr = 0 it does not matter what is value of size
- size = sizeof(Char)*(end - s+1);
- ptr = new char[size];
- memcpy(ptr,s,size);
- }
- template<typename Char>
- std::basic_string<Char> get() const
- {
- if(type==0 || *type!=typeid(Char))
- throw std::bad_cast();
- std::basic_string<Char> result = reinterpret_cast<Char const *>(ptr);
- return result;
- }
- private:
- std::type_info const *type;
- size_t size;
- char *ptr;
- };
- uint64_t flags_;
- int domain_id_;
- std::string time_zone_;
- string_set datetime_;
- struct data;
- data *d;
- };
- ///
- /// \brief This namespace includes all manipulators that can be used on IO streams
- ///
- namespace as {
- ///
- /// \defgroup manipulators I/O Stream manipulators
- ///
- /// @{
- ///
- ///
- /// Format values with "POSIX" or "C" locale. Note, if locale was created with additional non-classic locale then
- /// These numbers may be localized
- ///
-
- inline std::ios_base & posix(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::posix);
- return ios;
- }
- ///
- /// Format a number. Note, unlike standard number formatting, integers would be treated like real numbers when std::fixed or
- /// std::scientific manipulators were applied
- ///
- inline std::ios_base & number(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::number);
- return ios;
- }
-
- ///
- /// Format currency, number is treated like amount of money
- ///
- inline std::ios_base & currency(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::currency);
- return ios;
- }
-
- ///
- /// Format percent, value 0.3 is treated as 30%.
- ///
- inline std::ios_base & percent(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::percent);
- return ios;
- }
-
- ///
- /// Format a date, number is treated as POSIX time
- ///
- inline std::ios_base & date(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::date);
- return ios;
- }
- ///
- /// Format a time, number is treated as POSIX time
- ///
- inline std::ios_base & time(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::time);
- return ios;
- }
- ///
- /// Format a date and time, number is treated as POSIX time
- ///
- inline std::ios_base & datetime(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::datetime);
- return ios;
- }
- ///
- /// Create formatted date time, Please note, this manipulator only changes formatting mode,
- /// and not format itself, so you are probably looking for ftime manipulator
- ///
- inline std::ios_base & strftime(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::strftime);
- return ios;
- }
-
- ///
- /// Spell the number, like "one hundred and ten"
- ///
- inline std::ios_base & spellout(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::spellout);
- return ios;
- }
-
- ///
- /// Write an order of the number like 4th.
- ///
- inline std::ios_base & ordinal(std::ios_base & ios)
- {
- ios_info::get(ios).display_flags(flags::ordinal);
- return ios;
- }
- ///
- /// Set default currency formatting style -- national, like "$"
- ///
- inline std::ios_base & currency_default(std::ios_base & ios)
- {
- ios_info::get(ios).currency_flags(flags::currency_default);
- return ios;
- }
- ///
- /// Set ISO currency formatting style, like "USD", (requires ICU >= 4.2)
- ///
- inline std::ios_base & currency_iso(std::ios_base & ios)
- {
- ios_info::get(ios).currency_flags(flags::currency_iso);
- return ios;
- }
- ///
- /// Set national currency formatting style, like "$"
- ///
- inline std::ios_base & currency_national(std::ios_base & ios)
- {
- ios_info::get(ios).currency_flags(flags::currency_national);
- return ios;
- }
- ///
- /// set default (medium) time formatting style
- ///
- inline std::ios_base & time_default(std::ios_base & ios)
- {
- ios_info::get(ios).time_flags(flags::time_default);
- return ios;
- }
- ///
- /// set short time formatting style
- ///
- inline std::ios_base & time_short(std::ios_base & ios)
- {
- ios_info::get(ios).time_flags(flags::time_short);
- return ios;
- }
- ///
- /// set medium time formatting style
- ///
- inline std::ios_base & time_medium(std::ios_base & ios)
- {
- ios_info::get(ios).time_flags(flags::time_medium);
- return ios;
- }
- ///
- /// set long time formatting style
- ///
- inline std::ios_base & time_long(std::ios_base & ios)
- {
- ios_info::get(ios).time_flags(flags::time_long);
- return ios;
- }
- ///
- /// set full time formatting style
- ///
- inline std::ios_base & time_full(std::ios_base & ios)
- {
- ios_info::get(ios).time_flags(flags::time_full);
- return ios;
- }
- ///
- /// set default (medium) date formatting style
- ///
- inline std::ios_base & date_default(std::ios_base & ios)
- {
- ios_info::get(ios).date_flags(flags::date_default);
- return ios;
- }
- ///
- /// set short date formatting style
- ///
- inline std::ios_base & date_short(std::ios_base & ios)
- {
- ios_info::get(ios).date_flags(flags::date_short);
- return ios;
- }
- ///
- /// set medium date formatting style
- ///
- inline std::ios_base & date_medium(std::ios_base & ios)
- {
- ios_info::get(ios).date_flags(flags::date_medium);
- return ios;
- }
- ///
- /// set long date formatting style
- ///
- inline std::ios_base & date_long(std::ios_base & ios)
- {
- ios_info::get(ios).date_flags(flags::date_long);
- return ios;
- }
- ///
- /// set full date formatting style
- ///
- inline std::ios_base & date_full(std::ios_base & ios)
- {
- ios_info::get(ios).date_flags(flags::date_full);
- return ios;
- }
-
-
- /// \cond INTERNAL
- namespace details {
- template<typename CharType>
- struct add_ftime {
- std::basic_string<CharType> ftime;
- void apply(std::basic_ios<CharType> &ios) const
- {
- ios_info::get(ios).date_time_pattern(ftime);
- as::strftime(ios);
- }
- };
- template<typename CharType>
- std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,add_ftime<CharType> const &fmt)
- {
- fmt.apply(out);
- return out;
- }
-
- template<typename CharType>
- std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,add_ftime<CharType> const &fmt)
- {
- fmt.apply(in);
- return in;
- }
- }
- /// \endcond
- ///
- /// Set strftime like formatting string
- ///
- /// Please note, formatting flags are very similar but not exactly the same as flags for C function strftime.
- /// Differences: some flags as "%e" do not add blanks to fill text up to two spaces, not all flags supported.
- ///
- /// Flags:
- /// - "%a" -- Abbreviated weekday (Sun.)
- /// - "%A" -- Full weekday (Sunday)
- /// - "%b" -- Abbreviated month (Jan.)
- /// - "%B" -- Full month (January)
- /// - "%c" -- Locale date-time format. **Note:** prefer using "as::datetime"
- /// - "%d" -- Day of Month [01,31]
- /// - "%e" -- Day of Month [1,31]
- /// - "%h" -- Same as "%b"
- /// - "%H" -- 24 clock hour [00,23]
- /// - "%I" -- 12 clock hour [01,12]
- /// - "%j" -- Day of year [1,366]
- /// - "%m" -- Month [01,12]
- /// - "%M" -- Minute [00,59]
- /// - "%n" -- New Line
- /// - "%p" -- AM/PM in locale representation
- /// - "%r" -- Time with AM/PM, same as "%I:%M:%S %p"
- /// - "%R" -- Same as "%H:%M"
- /// - "%S" -- Second [00,61]
- /// - "%t" -- Tab character
- /// - "%T" -- Same as "%H:%M:%S"
- /// - "%x" -- Local date representation. **Note:** prefer using "as::date"
- /// - "%X" -- Local time representation. **Note:** prefer using "as::time"
- /// - "%y" -- Year [00,99]
- /// - "%Y" -- 4 digits year. (2009)
- /// - "%Z" -- Time Zone
- /// - "%%" -- Percent symbol
- ///
- template<typename CharType>
- #ifdef BOOST_LOCALE_DOXYGEN
- unspecified_type
- #else
- details::add_ftime<CharType>
- #endif
- ftime(std::basic_string<CharType> const &format)
- {
- details::add_ftime<CharType> fmt;
- fmt.ftime=format;
- return fmt;
- }
- ///
- /// See ftime(std::basic_string<CharType> const &format)
- ///
- template<typename CharType>
- #ifdef BOOST_LOCALE_DOXYGEN
- unspecified_type
- #else
- details::add_ftime<CharType>
- #endif
- ftime(CharType const *format)
- {
- details::add_ftime<CharType> fmt;
- fmt.ftime=format;
- return fmt;
- }
- /// \cond INTERNAL
- namespace details {
- struct set_timezone {
- std::string id;
- };
- template<typename CharType>
- std::basic_ostream<CharType> &operator<<(std::basic_ostream<CharType> &out,set_timezone const &fmt)
- {
- ios_info::get(out).time_zone(fmt.id);
- return out;
- }
-
- template<typename CharType>
- std::basic_istream<CharType> &operator>>(std::basic_istream<CharType> &in,set_timezone const &fmt)
- {
- ios_info::get(in).time_zone(fmt.id);
- return in;
- }
- }
- /// \endcond
-
- ///
- /// Set GMT time zone to stream
- ///
- inline std::ios_base &gmt(std::ios_base &ios)
- {
- ios_info::get(ios).time_zone("GMT");
- return ios;
- }
- ///
- /// Set local time zone to stream
- ///
- inline std::ios_base &local_time(std::ios_base &ios)
- {
- ios_info::get(ios).time_zone(time_zone::global());
- return ios;
- }
- ///
- /// Set time zone using \a id
- ///
- inline
- #ifdef BOOST_LOCALE_DOXYGEN
- unspecified_type
- #else
- details::set_timezone
- #endif
- time_zone(char const *id)
- {
- details::set_timezone tz;
- tz.id=id;
- return tz;
- }
- ///
- /// Set time zone using \a id
- ///
- inline
- #ifdef BOOST_LOCALE_DOXYGEN
- unspecified_type
- #else
- details::set_timezone
- #endif
- time_zone(std::string const &id)
- {
- details::set_timezone tz;
- tz.id=id;
- return tz;
- }
- ///
- /// @}
- ///
- } // as manipulators
-
- } // locale
- } // boost
- #ifdef BOOST_MSVC
- #pragma warning(pop)
- #endif
- #endif
- // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
|