Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-01 08:18:50

0001 //
0002 // Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
0003 // Copyright (c) 2022-2023 Alexander Grund
0004 //
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 
0008 #ifndef BOOST_LOCALE_FORMATTING_HPP_INCLUDED
0009 #define BOOST_LOCALE_FORMATTING_HPP_INCLUDED
0010 
0011 #include <boost/locale/detail/any_string.hpp>
0012 #include <boost/locale/time_zone.hpp>
0013 #include <cstdint>
0014 #include <cstring>
0015 #include <istream>
0016 #include <ostream>
0017 #include <string>
0018 
0019 #ifdef BOOST_MSVC
0020 #    pragma warning(push)
0021 #    pragma warning(disable : 4275 4251 4231 4660)
0022 #endif
0023 
0024 namespace boost { namespace locale {
0025 
0026     /// \brief This namespace holds additional formatting
0027     /// flags that can be set using ios_info.
0028     namespace flags {
0029 
0030         /// Formatting flags, each one of them has corresponding manipulation
0031         /// in namespace \a as
0032         enum display_flags_type {
0033             posix = 0,
0034             number = 1,
0035             currency = 2,
0036             percent = 3,
0037             date = 4,
0038             time = 5,
0039             datetime = 6,
0040             strftime = 7,
0041             spellout = 8,
0042             ordinal = 9,
0043 
0044             display_flags_mask = 31,
0045 
0046             currency_default = 0 << 5,
0047             currency_iso = 1 << 5,
0048             currency_national = 2 << 5,
0049 
0050             currency_flags_mask = 3 << 5,
0051 
0052             time_default = 0 << 7,
0053             time_short = 1 << 7,
0054             time_medium = 2 << 7,
0055             time_long = 3 << 7,
0056             time_full = 4 << 7,
0057             time_flags_mask = 7 << 7,
0058 
0059             date_default = 0 << 10,
0060             date_short = 1 << 10,
0061             date_medium = 2 << 10,
0062             date_long = 3 << 10,
0063             date_full = 4 << 10,
0064             date_flags_mask = 7 << 10,
0065         };
0066 
0067         /// Special string patterns that can be used for text formatting
0068         enum pattern_type {
0069             datetime_pattern, ///< strftime like formatting
0070             time_zone_id      ///< time zone name
0071         };
0072 
0073         /// Special integer values that can be used for formatting
0074         enum value_type {
0075             domain_id ///< Domain code - for message formatting
0076         };
0077 
0078     } // namespace flags
0079 
0080     /// \brief This class holds external data beyond existing fmtflags that std::ios_base holds
0081     ///
0082     /// You should almost never create this object directly. Instead, you should access it via
0083     /// ios_info::get(stream_object) static member function. It automatically creates default formatting data for that
0084     /// stream
0085     class BOOST_LOCALE_DECL ios_info {
0086     public:
0087         /// \cond INTERNAL
0088         ios_info();
0089         ios_info(const ios_info&);
0090         ios_info& operator=(const ios_info&);
0091         ~ios_info();
0092         /// \endcond
0093 
0094         /// Get ios_info instance for specific stream object
0095         static ios_info& get(std::ios_base& ios);
0096 
0097         /// Set flags that define how to format data, e.g. number, spell, currency etc.
0098         void display_flags(uint64_t flags);
0099         /// Get flags that define how to format data, e.g. number, spell, currency etc.
0100         uint64_t display_flags() const;
0101 
0102         /// Set flags that define how to format currency
0103         void currency_flags(uint64_t flags);
0104         /// Get flags that define how to format currency
0105         uint64_t currency_flags() const;
0106 
0107         /// Set flags that define how to format date
0108         void date_flags(uint64_t flags);
0109         /// Get flags that define how to format date
0110         uint64_t date_flags() const;
0111 
0112         /// Set flags that define how to format time
0113         void time_flags(uint64_t flags);
0114         /// Get flags that define how to format time
0115         uint64_t time_flags() const;
0116 
0117         /// Set special message domain identification
0118         void domain_id(int);
0119         /// Get special message domain identification
0120         int domain_id() const;
0121 
0122         /// Set time zone for formatting dates and time
0123         void time_zone(const std::string&);
0124         /// Get time zone for formatting dates and time
0125         std::string time_zone() const;
0126 
0127         /// Set date/time pattern (strftime like)
0128         template<typename CharType>
0129         void date_time_pattern(const std::basic_string<CharType>& str)
0130         {
0131             datetime_.set<CharType>(str);
0132         }
0133         /// Get date/time pattern (strftime like)
0134         template<typename CharType>
0135         std::basic_string<CharType> date_time_pattern() const
0136         {
0137             return datetime_.get<CharType>();
0138         }
0139 
0140         /// \cond INTERNAL
0141         void on_imbue();
0142         /// \endcond
0143 
0144     private:
0145         uint64_t flags_;
0146         int domain_id_;
0147         std::string time_zone_;
0148         detail::any_string datetime_;
0149     };
0150 
0151     /// \brief This namespace includes all manipulators that can be used on IO streams
0152     namespace as {
0153         /// \defgroup manipulators I/O Stream manipulators
0154         ///
0155         /// @{
0156 
0157         /// Format values with "POSIX" or "C"  locale. Note, if locale was created with additional non-classic locale
0158         /// then These numbers may be localized
0159         inline std::ios_base& posix(std::ios_base& ios)
0160         {
0161             ios_info::get(ios).display_flags(flags::posix);
0162             return ios;
0163         }
0164 
0165         /// Format a number. Note, unlike standard number formatting, integers would be treated like real numbers when
0166         /// std::fixed or std::scientific manipulators were applied
0167         inline std::ios_base& number(std::ios_base& ios)
0168         {
0169             ios_info::get(ios).display_flags(flags::number);
0170             return ios;
0171         }
0172 
0173         /// Format currency, number is treated like amount of money
0174         inline std::ios_base& currency(std::ios_base& ios)
0175         {
0176             ios_info::get(ios).display_flags(flags::currency);
0177             return ios;
0178         }
0179 
0180         /// Format percent, value 0.3 is treated as 30%.
0181         inline std::ios_base& percent(std::ios_base& ios)
0182         {
0183             ios_info::get(ios).display_flags(flags::percent);
0184             return ios;
0185         }
0186 
0187         /// Format a date, number is treated as POSIX time
0188         inline std::ios_base& date(std::ios_base& ios)
0189         {
0190             ios_info::get(ios).display_flags(flags::date);
0191             return ios;
0192         }
0193 
0194         /// Format a time, number is treated as POSIX time
0195         inline std::ios_base& time(std::ios_base& ios)
0196         {
0197             ios_info::get(ios).display_flags(flags::time);
0198             return ios;
0199         }
0200 
0201         /// Format a date and time, number is treated as POSIX time
0202         inline std::ios_base& datetime(std::ios_base& ios)
0203         {
0204             ios_info::get(ios).display_flags(flags::datetime);
0205             return ios;
0206         }
0207 
0208         /// Create formatted date time, Please note, this manipulator only changes formatting mode,
0209         /// and not format itself, so you are probably looking for ftime manipulator
0210         inline std::ios_base& strftime(std::ios_base& ios)
0211         {
0212             ios_info::get(ios).display_flags(flags::strftime);
0213             return ios;
0214         }
0215 
0216         /// Spell the number, like "one hundred and ten"
0217         inline std::ios_base& spellout(std::ios_base& ios)
0218         {
0219             ios_info::get(ios).display_flags(flags::spellout);
0220             return ios;
0221         }
0222 
0223         /// Write an order of the number like 4th.
0224         inline std::ios_base& ordinal(std::ios_base& ios)
0225         {
0226             ios_info::get(ios).display_flags(flags::ordinal);
0227             return ios;
0228         }
0229 
0230         /// Set default currency formatting style -- national, like "$"
0231         inline std::ios_base& currency_default(std::ios_base& ios)
0232         {
0233             ios_info::get(ios).currency_flags(flags::currency_default);
0234             return ios;
0235         }
0236 
0237         /// Set ISO currency formatting style, like "USD", (requires ICU >= 4.2)
0238         inline std::ios_base& currency_iso(std::ios_base& ios)
0239         {
0240             ios_info::get(ios).currency_flags(flags::currency_iso);
0241             return ios;
0242         }
0243 
0244         /// Set national currency formatting style, like "$"
0245         inline std::ios_base& currency_national(std::ios_base& ios)
0246         {
0247             ios_info::get(ios).currency_flags(flags::currency_national);
0248             return ios;
0249         }
0250 
0251         /// set default (medium) time formatting style
0252         inline std::ios_base& time_default(std::ios_base& ios)
0253         {
0254             ios_info::get(ios).time_flags(flags::time_default);
0255             return ios;
0256         }
0257 
0258         /// set short time formatting style
0259         inline std::ios_base& time_short(std::ios_base& ios)
0260         {
0261             ios_info::get(ios).time_flags(flags::time_short);
0262             return ios;
0263         }
0264 
0265         /// set medium time formatting style
0266         inline std::ios_base& time_medium(std::ios_base& ios)
0267         {
0268             ios_info::get(ios).time_flags(flags::time_medium);
0269             return ios;
0270         }
0271 
0272         /// set long time formatting style
0273         inline std::ios_base& time_long(std::ios_base& ios)
0274         {
0275             ios_info::get(ios).time_flags(flags::time_long);
0276             return ios;
0277         }
0278 
0279         /// set full time formatting style
0280         inline std::ios_base& time_full(std::ios_base& ios)
0281         {
0282             ios_info::get(ios).time_flags(flags::time_full);
0283             return ios;
0284         }
0285 
0286         /// set default (medium) date formatting style
0287         inline std::ios_base& date_default(std::ios_base& ios)
0288         {
0289             ios_info::get(ios).date_flags(flags::date_default);
0290             return ios;
0291         }
0292 
0293         /// set short date formatting style
0294         inline std::ios_base& date_short(std::ios_base& ios)
0295         {
0296             ios_info::get(ios).date_flags(flags::date_short);
0297             return ios;
0298         }
0299 
0300         /// set medium date formatting style
0301         inline std::ios_base& date_medium(std::ios_base& ios)
0302         {
0303             ios_info::get(ios).date_flags(flags::date_medium);
0304             return ios;
0305         }
0306 
0307         /// set long date formatting style
0308         inline std::ios_base& date_long(std::ios_base& ios)
0309         {
0310             ios_info::get(ios).date_flags(flags::date_long);
0311             return ios;
0312         }
0313 
0314         /// set full date formatting style
0315         inline std::ios_base& date_full(std::ios_base& ios)
0316         {
0317             ios_info::get(ios).date_flags(flags::date_full);
0318             return ios;
0319         }
0320 
0321         /// \cond INTERNAL
0322         namespace detail {
0323             inline bool is_datetime_display_flags(const uint64_t display_flags)
0324             {
0325                 return (display_flags == flags::date || display_flags == flags::time || display_flags == flags::datetime
0326                         || display_flags == flags::strftime);
0327             }
0328 
0329             template<typename CharType>
0330             struct add_ftime {
0331                 std::basic_string<CharType> ftime;
0332 
0333                 void apply(std::basic_ios<CharType>& ios) const
0334                 {
0335                     ios_info::get(ios).date_time_pattern(ftime);
0336                     as::strftime(ios);
0337                 }
0338             };
0339 
0340             template<typename CharType>
0341             std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const add_ftime<CharType>& fmt)
0342             {
0343                 fmt.apply(out);
0344                 return out;
0345             }
0346 
0347             template<typename CharType>
0348             std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const add_ftime<CharType>& fmt)
0349             {
0350                 fmt.apply(in);
0351                 return in;
0352             }
0353 
0354         } // namespace detail
0355         /// \endcond
0356 
0357         /// Set strftime like formatting string
0358         ///
0359         /// Please note, formatting flags are very similar but not exactly the same as flags for C function strftime.
0360         /// Differences: some flags as "%e" do not add blanks to fill text up to two spaces, not all flags supported.
0361         ///
0362         /// Flags:
0363         /// -   "%a" -- Abbreviated  weekday (Sun.)
0364         /// -   "%A" -- Full weekday (Sunday)
0365         /// -   "%b" -- Abbreviated month (Jan.)
0366         /// -   "%B" -- Full month (January)
0367         /// -   "%c" -- Locale date-time format. **Note:** prefer using "as::datetime"
0368         /// -   "%d" -- Day of Month [01,31]
0369         /// -   "%e" -- Day of Month [1,31]
0370         /// -   "%h" -- Same as "%b"
0371         /// -   "%H" -- 24 clock hour [00,23]
0372         /// -   "%I" -- 12 clock hour [01,12]
0373         /// -   "%j" -- Day of year [1,366]
0374         /// -   "%m" -- Month [01,12]
0375         /// -   "%M" -- Minute [00,59]
0376         /// -   "%n" -- New Line
0377         /// -   "%p" -- AM/PM in locale representation
0378         /// -   "%r" -- Time with AM/PM, same as "%I:%M:%S %p"
0379         /// -   "%R" -- Same as "%H:%M"
0380         /// -   "%S" -- Second [00,61]
0381         /// -   "%t" -- Tab character
0382         /// -   "%T" -- Same as "%H:%M:%S"
0383         /// -   "%x" -- Local date representation. **Note:** prefer using "as::date"
0384         /// -   "%X" -- Local time representation. **Note:** prefer using "as::time"
0385         /// -   "%y" -- Year [00,99]
0386         /// -   "%Y" -- 4 digits year. (2009)
0387         /// -   "%Z" -- Time Zone
0388         /// -   "%%" -- Percent symbol
0389         ///
0390 
0391         template<typename CharType>
0392 #ifdef BOOST_LOCALE_DOXYGEN
0393         unspecified_type
0394 #else
0395         detail::add_ftime<CharType>
0396 #endif
0397         ftime(const std::basic_string<CharType>& format)
0398         {
0399             detail::add_ftime<CharType> fmt;
0400             fmt.ftime = format;
0401             return fmt;
0402         }
0403 
0404         /// See ftime(std::basic_string<CharType> const &format)
0405         template<typename CharType>
0406 #ifdef BOOST_LOCALE_DOXYGEN
0407         unspecified_type
0408 #else
0409         detail::add_ftime<CharType>
0410 #endif
0411         ftime(const CharType* format)
0412         {
0413             detail::add_ftime<CharType> fmt;
0414             fmt.ftime = format;
0415             return fmt;
0416         }
0417 
0418         /// \cond INTERNAL
0419         namespace detail {
0420             struct set_timezone {
0421                 std::string id;
0422             };
0423             template<typename CharType>
0424             std::basic_ostream<CharType>& operator<<(std::basic_ostream<CharType>& out, const set_timezone& fmt)
0425             {
0426                 ios_info::get(out).time_zone(fmt.id);
0427                 return out;
0428             }
0429 
0430             template<typename CharType>
0431             std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& in, const set_timezone& fmt)
0432             {
0433                 ios_info::get(in).time_zone(fmt.id);
0434                 return in;
0435             }
0436         } // namespace detail
0437         /// \endcond
0438 
0439         /// Set GMT time zone to stream
0440         inline std::ios_base& gmt(std::ios_base& ios)
0441         {
0442             ios_info::get(ios).time_zone("GMT");
0443             return ios;
0444         }
0445 
0446         /// Set local time zone to stream
0447         inline std::ios_base& local_time(std::ios_base& ios)
0448         {
0449             ios_info::get(ios).time_zone(time_zone::global());
0450             return ios;
0451         }
0452 
0453         /// Set time zone using \a id
0454         inline
0455 #ifdef BOOST_LOCALE_DOXYGEN
0456           unspecified_type
0457 #else
0458           detail::set_timezone
0459 #endif
0460           time_zone(const char* id)
0461         {
0462             detail::set_timezone tz;
0463             tz.id = id;
0464             return tz;
0465         }
0466 
0467         /// Set time zone using \a id
0468         inline
0469 #ifdef BOOST_LOCALE_DOXYGEN
0470           unspecified_type
0471 #else
0472           detail::set_timezone
0473 #endif
0474           time_zone(const std::string& id)
0475         {
0476             detail::set_timezone tz;
0477             tz.id = id;
0478             return tz;
0479         }
0480 
0481         /// @}
0482 
0483     } // namespace as
0484 
0485 }} // namespace boost::locale
0486 
0487 #ifdef BOOST_MSVC
0488 #    pragma warning(pop)
0489 #endif
0490 
0491 #endif