LCOV - code coverage report
Current view: top level - snaplogger - ordinal_indicator.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 115 115 100.0 %
Date: 2022-01-29 21:11:29 Functions: 95 95 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2021  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/snaplogger
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License along
      17             : // with this program; if not, write to the Free Software Foundation, Inc.,
      18             : // 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      19             : //
      20             : 
      21             : /** \file
      22             :  * \brief Functions to return a string representing the ordinal indicator.
      23             :  *
      24             :  * A few languages make use of ordinal indicators such as "st" for first
      25             :  * in English. These indicators may further have a feminin variant as
      26             :  * in French (1er and 1ere--accent missing here, to avoid UTF-8 in our
      27             :  * source code).
      28             :  *
      29             :  * The language is very important although we offer functions that return
      30             :  * the ordinal indicator in each language, you probably want to use the
      31             :  * main function that will return the indicator depending on the language.
      32             :  *
      33             :  * \note
      34             :  * The ordinal indicator changes even within one language. The default can
      35             :  * be used by more languages (those that do not otherwise offer an ordinal
      36             :  * indicator).
      37             :  *
      38             :  * \sa https://en.wikipedia.org/wiki/Ordinal_indicator
      39             :  * \sa https://fr.wikipedia.org/wiki/Indicateur_ordinal
      40             :  */
      41             : 
      42             : // self
      43             : //
      44             : #include    "snaplogger/ordinal_indicator.h"
      45             : 
      46             : 
      47             : // snapdev lib
      48             : //
      49             : #include    <snapdev/not_used.h>
      50             : 
      51             : 
      52             : // C++ lib
      53             : //
      54             : #include    <string>
      55             : 
      56             : 
      57             : 
      58             : namespace snaplogger
      59             : {
      60             : 
      61             : 
      62             : namespace
      63             : {
      64             : 
      65             : 
      66             : 
      67             : // WARNING: to simplify the usage in the find_values() functions, the flags
      68             : //          are bit numbers, not masks
      69             : //
      70             : typedef std::uint16_t           flag_t;
      71             : 
      72             : flag_t                          FLAG_TENTH = 0;  // use (n % 10) instead of n to do the search unless `(n % 100) E { 11, 12, 13 }` is true
      73             : 
      74             : 
      75             : 
      76             : struct indicator_t
      77             : {
      78             :     std::uint16_t       f_count = 0;
      79             :     std::uint16_t       f_flags = 0;
      80             :     std::uint32_t       f_languages = 0;
      81             :     std::uint32_t       f_genders = 0;
      82             :     std::uint32_t       f_numbers = 0;
      83             :     std::uint32_t       f_secondary_forms = 0;
      84             :     char const *        f_ordinal_indicator = nullptr;
      85             : };
      86             : 
      87             : 
      88             : 
      89             : 
      90             : template<typename T>
      91             : class indicator_value
      92             : {
      93             : public:
      94             :     typedef T   value_t;
      95             : 
      96         120 :     constexpr indicator_value<T>(T const v)
      97         120 :         : f_value(v)
      98             :     {
      99         120 :     }
     100             : 
     101         110 :     constexpr value_t get() const
     102             :     {
     103         110 :         return f_value;
     104             :     }
     105             : 
     106             : private:
     107             :     value_t     f_value;
     108             : };
     109             : 
     110             : 
     111             : 
     112             : 
     113             : class specific_count
     114             :     : public indicator_value<std::uint16_t>
     115             : {
     116             : public:
     117          10 :     constexpr specific_count()
     118          10 :         : indicator_value<std::uint16_t>(0)
     119             :     {
     120          10 :     }
     121             : 
     122          10 :     constexpr specific_count(std::uint16_t c)
     123          10 :         : indicator_value<std::uint16_t>(c)
     124             :     {
     125          10 :     }
     126             : };
     127             : 
     128             : 
     129             : class indicator_flag
     130             :     : public indicator_value<flag_t>
     131             : {
     132             : public:
     133          10 :     constexpr indicator_flag()
     134          10 :         : indicator_value<flag_t>(static_cast<flag_t>(-1))
     135             :     {
     136          10 :     }
     137             : 
     138          10 :     constexpr indicator_flag(flag_t f)
     139          10 :         : indicator_value<flag_t>(f)
     140             :     {
     141          10 :     }
     142             : };
     143             : 
     144             : 
     145             : class indicator_language
     146             :     : public indicator_value<language_t>
     147             : {
     148             : public:
     149             :     constexpr indicator_language()
     150             :         : indicator_value<language_t>(language_t::LANGUAGE_DEFAULT)
     151             :     {
     152             :     }
     153             : 
     154          10 :     constexpr indicator_language(language_t l)
     155          10 :         : indicator_value<language_t>(l)
     156             :     {
     157          10 :     }
     158             : };
     159             : 
     160             : 
     161             : class indicator_gender
     162             :     : public indicator_value<gender_t>
     163             : {
     164             : public:
     165             :     constexpr indicator_gender()
     166             :         : indicator_value<gender_t>(gender_t::GENDER_MASCULINE)
     167             :     {
     168             :     }
     169             : 
     170          30 :     constexpr indicator_gender(gender_t g)
     171          30 :         : indicator_value<gender_t>(g)
     172             :     {
     173          30 :     }
     174             : };
     175             : 
     176             : 
     177             : class indicator_number
     178             :     : public indicator_value<number_t>
     179             : {
     180             : public:
     181             :     constexpr indicator_number()
     182             :         : indicator_value<number_t>(number_t::NUMBER_SINGULAR)
     183             :     {
     184             :     }
     185             : 
     186          20 :     constexpr indicator_number(number_t g)
     187          20 :         : indicator_value<number_t>(g)
     188             :     {
     189          20 :     }
     190             : };
     191             : 
     192             : 
     193             : class indicator_secondary_form
     194             :     : public indicator_value<secondary_form_t>
     195             : {
     196             : public:
     197             :     constexpr indicator_secondary_form()
     198             :         : indicator_value<secondary_form_t>(secondary_form_t::SECONDARY_FORM_FORMAL)
     199             :     {
     200             :     }
     201             : 
     202          10 :     constexpr indicator_secondary_form(secondary_form_t sf)
     203          10 :         : indicator_value<secondary_form_t>(sf)
     204             :     {
     205          10 :     }
     206             : };
     207             : 
     208             : 
     209             : class ordinal_indicator_string
     210             :     : public indicator_value<char const *>
     211             : {
     212             : public:
     213             :     constexpr ordinal_indicator_string()
     214             :         : indicator_value<char const *>(nullptr)
     215             :     {
     216             :     }
     217             : 
     218          10 :     constexpr ordinal_indicator_string(char const * indicator)
     219          10 :         : indicator_value<char const *>(indicator)
     220             :     {
     221          10 :     }
     222             : };
     223             : 
     224             : 
     225             : 
     226             : 
     227             : 
     228             : 
     229             : 
     230             : //template<typename T, typename F, class ...ARGS>
     231             : template<typename T, typename F>
     232          10 : constexpr typename std::enable_if<std::is_same<T, F>::value, std::uint32_t>::type find_values(F first)
     233             : {
     234          10 :     std::uint32_t const value(static_cast<std::uint32_t>(first.get()));
     235          10 :     if(value >= 32)
     236             :     {
     237          10 :         return 0;
     238             :     }
     239             :     return 1 << value;      // LCOV_EXCL_LINE
     240             : }
     241             : 
     242             : 
     243             : template<typename T, typename F>
     244          40 : constexpr typename std::enable_if<!std::is_same<T, F>::value, std::uint32_t>::type find_values(F first)
     245             : {
     246          40 :     snapdev::NOT_USED(first);
     247          40 :     return 0;
     248             : }
     249             : 
     250             : 
     251             : template<typename T, typename F, class ...ARGS>
     252          80 : constexpr typename std::enable_if<std::is_same<T, F>::value, std::uint32_t>::type find_values(F first, ARGS ...args)
     253             : {
     254          80 :     std::uint32_t const value(static_cast<std::uint32_t>(first.get()));
     255          80 :     if(value == static_cast<std::uint32_t>(-1))
     256             :     {
     257             :         return find_values<T>(args...);      // LCOV_EXCL_LINE
     258             :     }
     259          80 :     return (1 << value) | find_values<T>(args...);
     260             : }
     261             : 
     262             : 
     263             : template<typename T, typename F, class ...ARGS>
     264         380 : constexpr typename std::enable_if<!std::is_same<T, F>::value, std::uint32_t>::type find_values(F first, ARGS ...args)
     265             : {
     266         380 :     snapdev::NOT_USED(first);
     267         380 :     return find_values<T>(args...);
     268             : }
     269             : 
     270             : 
     271             : 
     272             : 
     273             : template<typename T, typename F, class ...ARGS>
     274          20 : constexpr typename std::enable_if<std::is_same<T, F>::value, typename T::value_t>::type find_option(F first, ARGS ...args)
     275             : {
     276          20 :     snapdev::NOT_USED(args...);
     277          20 :     return first.get();
     278             : }
     279             : 
     280             : 
     281             : template<typename T, typename F, class ...ARGS>
     282          90 : constexpr typename std::enable_if<!std::is_same<T, F>::value, typename T::value_t>::type find_option(F first, ARGS ...args)
     283             : {
     284          90 :     snapdev::NOT_USED(first);
     285          90 :     return find_option<T>(args...);
     286             : }
     287             : 
     288             : 
     289             : 
     290             : template<class ...ARGS>
     291          10 : constexpr indicator_t define_indicator(ARGS ...args)
     292             : {
     293             : #pragma GCC diagnostic push
     294             : #pragma GCC diagnostic ignored "-Wpedantic"
     295          90 :     indicator_t indicator =
     296             :     {
     297          20 :         .f_count =              find_option<specific_count>(args..., specific_count()),   // 0 = any
     298          20 :         .f_flags =              static_cast<flag_t>(find_values<indicator_flag>(args..., indicator_flag())),
     299          10 :         .f_languages =          find_values<indicator_language>(args...),
     300          10 :         .f_genders =            find_values<indicator_gender>(args...),
     301          10 :         .f_numbers =            find_values<indicator_number>(args...),
     302          10 :         .f_secondary_forms =    find_values<indicator_secondary_form>(args...),
     303          10 :         .f_ordinal_indicator =  find_option<ordinal_indicator_string>(args...),
     304             :     };
     305             : #pragma GCC diagnostic pop
     306             : 
     307          10 :     return indicator;
     308             : }
     309             : 
     310             : 
     311             : 
     312           2 : struct indicator_t g_indicators[]
     313             : {
     314             :     // Breton
     315             :     //
     316             :     define_indicator(
     317             :           specific_count(1)
     318             :         , indicator_language(language_t::LANGUAGE_BRETON)
     319             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     320             :         , indicator_gender(gender_t::GENDER_FEMININE)
     321             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     322             :         , indicator_number(number_t::NUMBER_SINGULAR)
     323             :         , indicator_number(number_t::NUMBER_PLURAL)
     324             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     325             :         , ordinal_indicator_string("a\xC3\xB1")
     326             :     ),
     327             :     define_indicator(
     328             :           specific_count(2)
     329             :         , indicator_language(language_t::LANGUAGE_BRETON)
     330             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     331             :         , indicator_gender(gender_t::GENDER_FEMININE)
     332             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     333             :         , indicator_number(number_t::NUMBER_SINGULAR)
     334             :         , indicator_number(number_t::NUMBER_PLURAL)
     335             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     336             :         , ordinal_indicator_string("l")
     337             :     ),
     338             :     define_indicator(
     339             :           specific_count(3)
     340             :         , indicator_language(language_t::LANGUAGE_BRETON)
     341             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     342             :         , indicator_gender(gender_t::GENDER_FEMININE)
     343             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     344             :         , indicator_number(number_t::NUMBER_SINGULAR)
     345             :         , indicator_number(number_t::NUMBER_PLURAL)
     346             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     347             :         , ordinal_indicator_string("de")
     348             :     ),
     349             :     define_indicator(
     350             :           specific_count(4)
     351             :         , indicator_language(language_t::LANGUAGE_BRETON)
     352             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     353             :         , indicator_gender(gender_t::GENDER_FEMININE)
     354             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     355             :         , indicator_number(number_t::NUMBER_SINGULAR)
     356             :         , indicator_number(number_t::NUMBER_PLURAL)
     357             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     358             :         , ordinal_indicator_string("re")
     359             :     ),
     360             :     define_indicator(
     361             :           indicator_language(language_t::LANGUAGE_BRETON)
     362             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     363             :         , indicator_gender(gender_t::GENDER_FEMININE)
     364             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     365             :         , indicator_number(number_t::NUMBER_SINGULAR)
     366             :         , indicator_number(number_t::NUMBER_PLURAL)
     367             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     368             :         , ordinal_indicator_string("vet")
     369             :     ),
     370             : 
     371             :     // English
     372             :     //
     373             :     define_indicator(
     374             :           specific_count(1)
     375             :         , indicator_flag(FLAG_TENTH)
     376             :         , indicator_language(language_t::LANGUAGE_ENGLISH)
     377             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     378             :         , indicator_gender(gender_t::GENDER_FEMININE)
     379             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     380             :         , indicator_number(number_t::NUMBER_SINGULAR)
     381             :         , indicator_number(number_t::NUMBER_PLURAL)
     382             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     383             :         , ordinal_indicator_string("st")
     384          22 :     ),
     385             :     define_indicator(
     386             :           specific_count(2)
     387             :         , indicator_flag(FLAG_TENTH)
     388             :         , indicator_language(language_t::LANGUAGE_ENGLISH)
     389             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     390             :         , indicator_gender(gender_t::GENDER_FEMININE)
     391             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     392             :         , indicator_number(number_t::NUMBER_SINGULAR)
     393             :         , indicator_number(number_t::NUMBER_PLURAL)
     394             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     395             :         , ordinal_indicator_string("nd")
     396          22 :     ),
     397             :     define_indicator(
     398             :           specific_count(2)
     399             :         , indicator_flag(FLAG_TENTH)
     400             :         , indicator_language(language_t::LANGUAGE_ENGLISH)
     401             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     402             :         , indicator_gender(gender_t::GENDER_FEMININE)
     403             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     404             :         , indicator_number(number_t::NUMBER_SINGULAR)
     405             :         , indicator_number(number_t::NUMBER_PLURAL)
     406             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     407             :         , ordinal_indicator_string("d")
     408          22 :     ),
     409             :     define_indicator(
     410             :           specific_count(3)
     411             :         , indicator_flag(FLAG_TENTH)
     412             :         , indicator_language(language_t::LANGUAGE_ENGLISH)
     413             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     414             :         , indicator_gender(gender_t::GENDER_FEMININE)
     415             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     416             :         , indicator_number(number_t::NUMBER_SINGULAR)
     417             :         , indicator_number(number_t::NUMBER_PLURAL)
     418             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     419             :         , ordinal_indicator_string("rd")
     420          22 :     ),
     421             :     define_indicator(
     422             :           specific_count(3)
     423             :         , indicator_flag(FLAG_TENTH)
     424             :         , indicator_language(language_t::LANGUAGE_ENGLISH)
     425             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     426             :         , indicator_gender(gender_t::GENDER_FEMININE)
     427             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     428             :         , indicator_number(number_t::NUMBER_SINGULAR)
     429             :         , indicator_number(number_t::NUMBER_PLURAL)
     430             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     431             :         , ordinal_indicator_string("d")
     432          22 :     ),
     433             :     define_indicator(
     434             :           indicator_language(language_t::LANGUAGE_ENGLISH)
     435             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     436             :         , indicator_gender(gender_t::GENDER_FEMININE)
     437             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     438             :         , indicator_number(number_t::NUMBER_SINGULAR)
     439             :         , indicator_number(number_t::NUMBER_PLURAL)
     440             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     441             :         , ordinal_indicator_string("th")
     442             :     ),
     443             : 
     444             :     // French
     445             :     //
     446             :     define_indicator(
     447             :           specific_count(1)
     448             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     449             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     450             :         , indicator_number(number_t::NUMBER_SINGULAR)
     451             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     452             :         , ordinal_indicator_string("er")
     453             :     ),
     454             :     define_indicator(
     455             :           specific_count(1)
     456             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     457             :         , indicator_gender(gender_t::GENDER_FEMININE)
     458             :         , indicator_number(number_t::NUMBER_SINGULAR)
     459             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     460             :         , ordinal_indicator_string("re")
     461             :     ),
     462             :     define_indicator(
     463             :           specific_count(1)
     464             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     465             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     466             :         , indicator_number(number_t::NUMBER_PLURAL)
     467             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     468             :         , ordinal_indicator_string("ers")
     469             :     ),
     470             :     define_indicator(
     471             :           specific_count(1)
     472             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     473             :         , indicator_gender(gender_t::GENDER_FEMININE)
     474             :         , indicator_number(number_t::NUMBER_PLURAL)
     475             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     476             :         , ordinal_indicator_string("res")
     477             :     ),
     478             :     define_indicator(
     479             :           specific_count(2)
     480             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     481             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     482             :         , indicator_number(number_t::NUMBER_SINGULAR)
     483             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_THREE)
     484             :         , ordinal_indicator_string("d")
     485             :     ),
     486             :     define_indicator(
     487             :           specific_count(2)
     488             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     489             :         , indicator_gender(gender_t::GENDER_FEMININE)
     490             :         , indicator_number(number_t::NUMBER_SINGULAR)
     491             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_THREE)
     492             :         , ordinal_indicator_string("de")
     493             :     ),
     494             :     define_indicator(
     495             :           specific_count(2)
     496             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     497             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     498             :         , indicator_number(number_t::NUMBER_PLURAL)
     499             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_THREE)
     500             :         , ordinal_indicator_string("ds")
     501             :     ),
     502             :     define_indicator(
     503             :           specific_count(2)
     504             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     505             :         , indicator_gender(gender_t::GENDER_FEMININE)
     506             :         , indicator_number(number_t::NUMBER_PLURAL)
     507             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_THREE)
     508             :         , ordinal_indicator_string("des")
     509             :     ),
     510             :     define_indicator(
     511             :           specific_count(2)
     512             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     513             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     514             :         , indicator_number(number_t::NUMBER_SINGULAR)
     515             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FOUR)
     516             :         , ordinal_indicator_string("nd")
     517             :     ),
     518             :     define_indicator(
     519             :           specific_count(2)
     520             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     521             :         , indicator_gender(gender_t::GENDER_FEMININE)
     522             :         , indicator_number(number_t::NUMBER_SINGULAR)
     523             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FOUR)
     524             :         , ordinal_indicator_string("nde")
     525             :     ),
     526             :     define_indicator(
     527             :           specific_count(2)
     528             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     529             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     530             :         , indicator_number(number_t::NUMBER_PLURAL)
     531             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FOUR)
     532             :         , ordinal_indicator_string("nds")
     533             :     ),
     534             :     define_indicator(
     535             :           specific_count(2)
     536             :         , indicator_language(language_t::LANGUAGE_FRENCH)
     537             :         , indicator_gender(gender_t::GENDER_FEMININE)
     538             :         , indicator_number(number_t::NUMBER_PLURAL)
     539             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FOUR)
     540             :         , ordinal_indicator_string("ndes")
     541             :     ),
     542             :     define_indicator(
     543             :           indicator_language(language_t::LANGUAGE_FRENCH)
     544             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     545             :         , indicator_gender(gender_t::GENDER_FEMININE)
     546             :         , indicator_number(number_t::NUMBER_SINGULAR)
     547             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     548             :         , ordinal_indicator_string("e")
     549             :     ),
     550             :     define_indicator(
     551             :           indicator_language(language_t::LANGUAGE_FRENCH)
     552             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     553             :         , indicator_gender(gender_t::GENDER_FEMININE)
     554             :         , indicator_number(number_t::NUMBER_PLURAL)
     555             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     556             :         , ordinal_indicator_string("es")
     557             :     ),
     558             :     define_indicator(
     559             :           indicator_language(language_t::LANGUAGE_FRENCH)
     560             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     561             :         , indicator_gender(gender_t::GENDER_FEMININE)
     562             :         , indicator_number(number_t::NUMBER_SINGULAR)
     563             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     564             :         , ordinal_indicator_string("\xC3\xA8me")
     565             :     ),
     566             :     define_indicator(
     567             :           indicator_language(language_t::LANGUAGE_FRENCH)
     568             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     569             :         , indicator_gender(gender_t::GENDER_FEMININE)
     570             :         , indicator_number(number_t::NUMBER_PLURAL)
     571             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     572             :         , ordinal_indicator_string("\xC3\xA8mes")
     573             :     ),
     574             :     define_indicator(
     575             :           indicator_language(language_t::LANGUAGE_FRENCH)
     576             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     577             :         , indicator_gender(gender_t::GENDER_FEMININE)
     578             :         , indicator_number(number_t::NUMBER_SINGULAR)
     579             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_TWO)
     580             :         , ordinal_indicator_string("i\xC3\xA8me")
     581             :     ),
     582             :     define_indicator(
     583             :           indicator_language(language_t::LANGUAGE_FRENCH)
     584             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     585             :         , indicator_gender(gender_t::GENDER_FEMININE)
     586             :         , indicator_number(number_t::NUMBER_PLURAL)
     587             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_TWO)
     588             :         , ordinal_indicator_string("i\xC3\xA8mes")
     589             :     ),
     590             : 
     591             :     // Francoprovincal
     592             :     //
     593             :     define_indicator(
     594             :           specific_count(1)
     595             :         , indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     596             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     597             :         , indicator_number(number_t::NUMBER_SINGULAR)
     598             :         , indicator_number(number_t::NUMBER_PLURAL)
     599             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     600             :         , ordinal_indicator_string("\xC3\xA9r")
     601             :     ),
     602             :     define_indicator(
     603             :           specific_count(1)
     604             :         , indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     605             :         , indicator_gender(gender_t::GENDER_FEMININE)
     606             :         , indicator_number(number_t::NUMBER_SINGULAR)
     607             :         , indicator_number(number_t::NUMBER_PLURAL)
     608             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     609             :         , ordinal_indicator_string("\xC3\xA9re")
     610             :     ),
     611             :     define_indicator(
     612             :           specific_count(2)
     613             :         , indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     614             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     615             :         , indicator_number(number_t::NUMBER_SINGULAR)
     616             :         , indicator_number(number_t::NUMBER_PLURAL)
     617             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     618             :         , ordinal_indicator_string("nd")
     619             :     ),
     620             :     define_indicator(
     621             :           specific_count(2)
     622             :         , indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     623             :         , indicator_gender(gender_t::GENDER_FEMININE)
     624             :         , indicator_number(number_t::NUMBER_SINGULAR)
     625             :         , indicator_number(number_t::NUMBER_PLURAL)
     626             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     627             :         , ordinal_indicator_string("nda")
     628             :     ),
     629             :     define_indicator(
     630             :           indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     631             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     632             :         , indicator_number(number_t::NUMBER_SINGULAR)
     633             :         , indicator_number(number_t::NUMBER_PLURAL)
     634             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     635             :         , ordinal_indicator_string("\xC3\xA9mo")
     636             :     ),
     637             :     define_indicator(
     638             :           indicator_language(language_t::LANGUAGE_FRANCOPROVENCAL)
     639             :         , indicator_gender(gender_t::GENDER_FEMININE)
     640             :         , indicator_number(number_t::NUMBER_SINGULAR)
     641             :         , indicator_number(number_t::NUMBER_PLURAL)
     642             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     643             :         , ordinal_indicator_string("\xC3\xA9ma")
     644             :     ),
     645             : 
     646             :     // Occitan
     647             :     //
     648             :     define_indicator(
     649             :           specific_count(1)
     650             :         , indicator_language(language_t::LANGUAGE_OCCITAN)
     651             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     652             :         , indicator_number(number_t::NUMBER_SINGULAR)
     653             :         , indicator_number(number_t::NUMBER_PLURAL)
     654             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     655             :         , ordinal_indicator_string("\xC3\xA8r")
     656             :     ),
     657             :     define_indicator(
     658             :           specific_count(1)
     659             :         , indicator_language(language_t::LANGUAGE_OCCITAN)
     660             :         , indicator_gender(gender_t::GENDER_FEMININE)
     661             :         , indicator_number(number_t::NUMBER_SINGULAR)
     662             :         , indicator_number(number_t::NUMBER_PLURAL)
     663             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     664             :         , ordinal_indicator_string("\xC3\xA8ra")
     665             :     ),
     666             :     define_indicator(
     667             :           specific_count(2)
     668             :         , indicator_language(language_t::LANGUAGE_OCCITAN)
     669             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     670             :         , indicator_number(number_t::NUMBER_SINGULAR)
     671             :         , indicator_number(number_t::NUMBER_PLURAL)
     672             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     673             :         , ordinal_indicator_string("nd")
     674             :     ),
     675             :     define_indicator(
     676             :           specific_count(2)
     677             :         , indicator_language(language_t::LANGUAGE_OCCITAN)
     678             :         , indicator_gender(gender_t::GENDER_FEMININE)
     679             :         , indicator_number(number_t::NUMBER_SINGULAR)
     680             :         , indicator_number(number_t::NUMBER_PLURAL)
     681             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     682             :         , ordinal_indicator_string("nda")
     683             :     ),
     684             :     define_indicator(
     685             :           indicator_language(language_t::LANGUAGE_OCCITAN)
     686             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     687             :         , indicator_number(number_t::NUMBER_SINGULAR)
     688             :         , indicator_number(number_t::NUMBER_PLURAL)
     689             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     690             :         , ordinal_indicator_string("en")
     691             :     ),
     692             :     define_indicator(
     693             :           indicator_language(language_t::LANGUAGE_OCCITAN)
     694             :         , indicator_gender(gender_t::GENDER_FEMININE)
     695             :         , indicator_number(number_t::NUMBER_SINGULAR)
     696             :         , indicator_number(number_t::NUMBER_PLURAL)
     697             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     698             :         , ordinal_indicator_string("ena")
     699             :     ),
     700             : 
     701             :     // Russian
     702             :     //
     703             :     define_indicator(
     704             :           indicator_language(language_t::LANGUAGE_RUSSIAN)
     705             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     706             :         , indicator_number(number_t::NUMBER_SINGULAR)
     707             :         , indicator_number(number_t::NUMBER_PLURAL)
     708             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     709             :         , ordinal_indicator_string("-\xD0\xB9")
     710             :     ),
     711             :     define_indicator(
     712             :           indicator_language(language_t::LANGUAGE_RUSSIAN)
     713             :         , indicator_gender(gender_t::GENDER_FEMININE)
     714             :         , indicator_number(number_t::NUMBER_SINGULAR)
     715             :         , indicator_number(number_t::NUMBER_PLURAL)
     716             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     717             :         , ordinal_indicator_string("-\xD1\x8F")
     718             :     ),
     719             :     define_indicator(
     720             :           indicator_language(language_t::LANGUAGE_RUSSIAN)
     721             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     722             :         , indicator_number(number_t::NUMBER_SINGULAR)
     723             :         , indicator_number(number_t::NUMBER_PLURAL)
     724             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     725             :         , ordinal_indicator_string("-\xD0\xB5")
     726             :     ),
     727             : 
     728             :     // Other Latin languages use pretty much the same notation
     729             :     //
     730             :     define_indicator(
     731             :           indicator_language(language_t::LANGUAGE_SPANISH)
     732             :         , indicator_language(language_t::LANGUAGE_PORTUGUESE)
     733             :         , indicator_language(language_t::LANGUAGE_ITALIAN)
     734             :         , indicator_language(language_t::LANGUAGE_GALICIAN)
     735             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     736             :         , indicator_number(number_t::NUMBER_SINGULAR)
     737             :         , indicator_number(number_t::NUMBER_PLURAL)
     738             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     739             :         , ordinal_indicator_string("\xC2\xBA")
     740             :     ),
     741             :     define_indicator(
     742             :           indicator_language(language_t::LANGUAGE_SPANISH)
     743             :         , indicator_language(language_t::LANGUAGE_PORTUGUESE)
     744             :         , indicator_language(language_t::LANGUAGE_ITALIAN)
     745             :         , indicator_language(language_t::LANGUAGE_GALICIAN)
     746             :         , indicator_gender(gender_t::GENDER_FEMININE)
     747             :         , indicator_number(number_t::NUMBER_SINGULAR)
     748             :         , indicator_number(number_t::NUMBER_PLURAL)
     749             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     750             :         , ordinal_indicator_string("\xC2\xAA")
     751             :     ),
     752             :     define_indicator(
     753             :           indicator_language(language_t::LANGUAGE_SPANISH)
     754             :         , indicator_language(language_t::LANGUAGE_PORTUGUESE)
     755             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     756             :         , indicator_number(number_t::NUMBER_SINGULAR)
     757             :         , indicator_number(number_t::NUMBER_PLURAL)
     758             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     759             :         , ordinal_indicator_string(".\xC2\xBA")
     760             :     ),
     761             :     define_indicator(
     762             :           indicator_language(language_t::LANGUAGE_SPANISH)
     763             :         , indicator_language(language_t::LANGUAGE_PORTUGUESE)
     764             :         , indicator_gender(gender_t::GENDER_FEMININE)
     765             :         , indicator_number(number_t::NUMBER_SINGULAR)
     766             :         , indicator_number(number_t::NUMBER_PLURAL)
     767             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_ONE)
     768             :         , ordinal_indicator_string(".\xC2\xAA")
     769             :     ),
     770             : 
     771             :     // Period Indicator
     772             :     //
     773             :     define_indicator(
     774             :           indicator_language(language_t::LANGUAGE_BASQUE)
     775             :         , indicator_language(language_t::LANGUAGE_BOSNIAN)
     776             :         , indicator_language(language_t::LANGUAGE_CROATIAN)
     777             :         , indicator_language(language_t::LANGUAGE_CZECH)
     778             :         , indicator_language(language_t::LANGUAGE_DANISH)
     779             :         , indicator_language(language_t::LANGUAGE_FAROESE)
     780             :         , indicator_language(language_t::LANGUAGE_FINNISH)
     781             :         , indicator_language(language_t::LANGUAGE_GERMAN)
     782             :         , indicator_language(language_t::LANGUAGE_ICELANDIC)
     783             :         , indicator_language(language_t::LANGUAGE_LATVIAN)
     784             :         , indicator_language(language_t::LANGUAGE_MONTENEGRIN)
     785             :         , indicator_language(language_t::LANGUAGE_NORWEGIAN)
     786             :         , indicator_language(language_t::LANGUAGE_SERBIAN)      // <- TODO: this is only for Arabic numbers
     787             :         , indicator_language(language_t::LANGUAGE_SLOVAK)
     788             :         , indicator_language(language_t::LANGUAGE_SLOVENE)
     789             :         , indicator_language(language_t::LANGUAGE_TURKISH)
     790             :         , indicator_gender(gender_t::GENDER_MASCULINE)
     791             :         , indicator_gender(gender_t::GENDER_FEMININE)
     792             :         , indicator_gender(gender_t::GENDER_NEUTRAL)
     793             :         , indicator_number(number_t::NUMBER_SINGULAR)
     794             :         , indicator_number(number_t::NUMBER_PLURAL)
     795             :         , indicator_secondary_form(secondary_form_t::SECONDARY_FORM_FORMAL)
     796             :         , ordinal_indicator_string(".")
     797             :     ),
     798         112 : };
     799             : 
     800             : }
     801             : 
     802             : 
     803             : 
     804             : /** \brief Define the language.
     805             :  *
     806             :  * The language to use to generate the indicated.
     807             :  *
     808             :  * By default is LANGUAGE_DEFAULT is used. This means nothing happens
     809             :  * (i.e. the indicator() function will always return an empty string).
     810             :  *
     811             :  * \param[in] l  The language to use to generate the indicator.
     812             :  *
     813             :  * \sa language()
     814             :  */
     815         563 : void ordinal_indicator::language(language_t l)
     816             : {
     817         563 :     f_language = l;
     818         563 : }
     819             : 
     820             : 
     821             : /** \brief Retrieve the current language of the ordinal indicator.
     822             :  *
     823             :  * This function returns the language definition of the ordinal indicator
     824             :  * object.
     825             :  *
     826             :  * \return The current language of the ordinal indicator.
     827             :  *
     828             :  * \sa language(language_t l)
     829             :  */
     830         523 : language_t ordinal_indicator::language() const
     831             : {
     832         523 :     return f_language;
     833             : }
     834             : 
     835             : 
     836             : /** \brief Change the grammatical gender.
     837             :  *
     838             :  * The ordinal indicator often depends on the grammatical gender in the
     839             :  * sentence including the number.
     840             :  *
     841             :  * \param[in] g  The new gender.
     842             :  *
     843             :  * \sa gender()
     844             :  */
     845       20668 : void ordinal_indicator::gender(gender_t g)
     846             : {
     847       20668 :     f_gender = g;
     848       20668 : }
     849             : 
     850             : 
     851             : /** \brief Retrieve the grammatical gender.
     852             :  *
     853             :  * This function retrieves the current grammatical gender.
     854             :  *
     855             :  * \return The current grammatical gender.
     856             :  *
     857             :  * \sa gender(gender_t g)
     858             :  */
     859         523 : gender_t ordinal_indicator::gender() const
     860             : {
     861         523 :     return f_gender;
     862             : }
     863             : 
     864             : 
     865             : /** \brief The number of the indicator.
     866             :  *
     867             :  * The number defines whether the singular or the plural version is to be
     868             :  * retrieved. For some languages (English) this makes no difference. For
     869             :  * others (French) it will force the plural version (i.e. append an 's'
     870             :  * to the French ordinal).
     871             :  *
     872             :  * By default, the number is set to singular.
     873             :  *
     874             :  * \param[in] n  The new number of the indicator.
     875             :  *
     876             :  * \sa number()
     877             :  */
     878       20640 : void ordinal_indicator::number(number_t n)
     879             : {
     880       20640 :     f_number = n;
     881       20640 : }
     882             : 
     883             : 
     884             : /** \brief Retrieve the current indicator number.
     885             :  *
     886             :  * This function returns whether the singular or plural version of the
     887             :  * ordinal indicator is to be returned.
     888             :  *
     889             :  * \return The current number of the indicator.
     890             :  *
     891             :  * \sa number(number_t n)
     892             :  */
     893         523 : number_t ordinal_indicator::number() const
     894             : {
     895         523 :     return f_number;
     896             : }
     897             : 
     898             : 
     899             : /** \brief Select a secondary form.
     900             :  *
     901             :  * By default, the formal form is returned by the indicator() function.
     902             :  * Some languages offer multiple ordinals for various numbers.
     903             :  *
     904             :  * For example, the Spanish form just uses an ordinal mark (a small 'o'
     905             :  * with an underscore) by default, but it is possible to add a period
     906             :  * just before that character. In French, the number 2 can be folloed
     907             :  * by an 'e' (deuxieme) or 'nd' (second). Etc.
     908             :  *
     909             :  * \param[in] sf  The new secondary form to use with indicator().
     910             :  *
     911             :  * \sa secondary_form()
     912             :  */
     913       20525 : void ordinal_indicator::secondary_form(secondary_form_t sf)
     914             : {
     915       20525 :     f_secondary_form = sf;
     916       20525 : }
     917             : 
     918             : 
     919             : /** \brief Retrieve the secondary form.
     920             :  *
     921             :  * This function returns the current secondary form.
     922             :  *
     923             :  * \return The current secondary form.
     924             :  *
     925             :  * \sa secondary_form(secondary_form_t sf)
     926             :  */
     927         523 : secondary_form_t ordinal_indicator::secondary_form() const
     928             : {
     929         523 :     return f_secondary_form;
     930             : }
     931             : 
     932             : 
     933             : /** \brief Determine the ordinal indicator for number \p n.
     934             :  *
     935             :  * This function returns the ordinal indicator for the input number \p n
     936             :  * as per all the specified parameters such as the language and
     937             :  * grammatical gender.
     938             :  *
     939             :  * This function can be called any number of times. Parameters can be changed
     940             :  * between calls and it will still work.
     941             :  *
     942             :  * \param[in] n  The number to be given an ordinal indicator.
     943             :  *
     944             :  * \return The ordinal indicator string or "" if no indicator is available.
     945             :  */
     946      117979 : char const * ordinal_indicator::indicator(long long n) const
     947             : {
     948      117979 :     if(n < 1)
     949             :     {
     950        1001 :         return "";
     951             :     }
     952             : 
     953      116978 :     int const tenth(n % 10);
     954      116978 :     int const hundredth(n % 100);
     955             : 
     956      116978 :     constexpr std::size_t const max(sizeof(g_indicators) / sizeof(g_indicators[0]));
     957     5098891 :     for(std::size_t idx(0); idx < max; ++idx)
     958             :     {
     959             :         // language
     960             :         //
     961     5098369 :         if((g_indicators[idx].f_languages & (1 << static_cast<std::uint32_t>(f_language))) == 0)
     962             :         {
     963     4744404 :             continue;
     964             :         }
     965             : 
     966             :         // gender (masculine, feminine, neutral)
     967             :         //
     968      353965 :         if((g_indicators[idx].f_genders & (1 << static_cast<std::uint32_t>(f_gender))) == 0)
     969             :         {
     970       92518 :             continue;
     971             :         }
     972             : 
     973             :         // number (plurial, singular)
     974             :         //
     975      261447 :         if((g_indicators[idx].f_numbers & (1 << static_cast<std::uint32_t>(f_number))) == 0)
     976             :         {
     977       53910 :             continue;
     978             :         }
     979             : 
     980             :         // another form than the formal form
     981             :         //
     982      207537 :         if((g_indicators[idx].f_secondary_forms & (1 << static_cast<std::uint32_t>(f_secondary_form))) == 0)
     983             :         {
     984       50487 :             continue;
     985             :         }
     986             : 
     987      157050 :         if(g_indicators[idx].f_count != 0
     988       81273 :         && g_indicators[idx].f_count != n
     989       40594 :         && ((g_indicators[idx].f_flags & (1 << FLAG_TENTH)) == 0
     990         714 :                     || g_indicators[idx].f_count != tenth
     991          71 :                     || hundredth == 11
     992          55 :                     || hundredth == 12
     993          28 :                     || hundredth == 13))
     994             :         {
     995       40594 :             continue;
     996             :         }
     997             : 
     998      116456 :         return g_indicators[idx].f_ordinal_indicator;
     999             :     }
    1000             : 
    1001         522 :     return "";
    1002             : }
    1003             : 
    1004             : 
    1005             : 
    1006             : 
    1007             : 
    1008             : 
    1009           6 : } // snaplogger namespace
    1010             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13