LCOV - code coverage report
Current view: top level - intl/icu/source/common - pluralmap.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 91 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : ******************************************************************************
       5             : * Copyright (C) 2015, International Business Machines Corporation and
       6             : * others. All Rights Reserved.
       7             : ******************************************************************************
       8             : *
       9             : * File pluralmap.h - PluralMap class that maps plural categories to values.
      10             : ******************************************************************************
      11             : */
      12             : 
      13             : #ifndef __PLURAL_MAP_H__
      14             : #define __PLURAL_MAP_H__
      15             : 
      16             : #include "unicode/uobject.h"
      17             : #include "cmemory.h"
      18             : 
      19             : U_NAMESPACE_BEGIN
      20             : 
      21             : class UnicodeString;
      22             : 
      23           0 : class U_COMMON_API PluralMapBase : public UMemory {
      24             : public:
      25             :     /**
      26             :      * The names of all the plural categories. NONE is not an actual plural
      27             :      * category, but rather represents the absense of a plural category.
      28             :      */
      29             :     enum Category {
      30             :         NONE = -1,
      31             :         OTHER,
      32             :         ZERO,
      33             :         ONE,
      34             :         TWO,
      35             :         FEW,
      36             :         MANY,
      37             :         CATEGORY_COUNT
      38             :     };
      39             : 
      40             :     /**
      41             :      * Converts a category name such as "zero", "one", "two", "few", "many"
      42             :      * or "other" to a category enum. Returns NONE for an unrecognized
      43             :      * category name.
      44             :      */
      45             :     static Category toCategory(const char *categoryName);
      46             : 
      47             :     /**
      48             :      * Converts a category name such as "zero", "one", "two", "few", "many"
      49             :      * or "other" to a category enum.  Returns NONE for urecongized
      50             :      * category name.
      51             :      */
      52             :     static Category toCategory(const UnicodeString &categoryName);
      53             : 
      54             :     /**
      55             :      * Converts a category to a name.
      56             :      * Passing NONE or CATEGORY_COUNT for category returns NULL.
      57             :      */
      58             :     static const char *getCategoryName(Category category);
      59             : };
      60             : 
      61             : /**
      62             :  * A Map of plural categories to values. It maintains ownership of the
      63             :  * values.
      64             :  *
      65             :  * Type T is the value type. T must provide the followng:
      66             :  * 1) Default constructor
      67             :  * 2) Copy constructor
      68             :  * 3) Assignment operator
      69             :  * 4) Must extend UMemory
      70             :  */
      71             : template<typename T>
      72             : class PluralMap : public PluralMapBase {
      73             : public:
      74             :     /**
      75             :      * Other category is maps to a copy of the default value.
      76             :      */
      77           0 :     PluralMap() : fOtherVariant() {
      78           0 :         initializeNew();
      79           0 :     }
      80             : 
      81             :     /**
      82             :      * Other category is mapped to otherVariant.
      83             :      */
      84           0 :     PluralMap(const T &otherVariant) : fOtherVariant(otherVariant) {
      85           0 :         initializeNew();
      86           0 :     }
      87             : 
      88           0 :     PluralMap(const PluralMap<T> &other) : fOtherVariant(other.fOtherVariant) {
      89           0 :         fVariants[0] = &fOtherVariant;
      90           0 :         for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
      91           0 :             fVariants[i] = other.fVariants[i] ?
      92           0 :                     new T(*other.fVariants[i]) : NULL;
      93             :         }
      94           0 :     }
      95             : 
      96           0 :     PluralMap<T> &operator=(const PluralMap<T> &other) {
      97           0 :         if (this == &other) {
      98           0 :             return *this;
      99             :         }
     100           0 :         for (int32_t i = 0; i < UPRV_LENGTHOF(fVariants); ++i) {
     101           0 :             if (fVariants[i] != NULL && other.fVariants[i] != NULL) {
     102           0 :                 *fVariants[i] = *other.fVariants[i];
     103           0 :             } else if (fVariants[i] != NULL) {
     104           0 :                 delete fVariants[i];
     105           0 :                 fVariants[i] = NULL;
     106           0 :             } else if (other.fVariants[i] != NULL) {
     107           0 :                 fVariants[i] = new T(*other.fVariants[i]);
     108             :             } else {
     109             :                 // do nothing
     110             :             }
     111             :         }
     112           0 :         return *this;
     113             :     }
     114             : 
     115           0 :     ~PluralMap() {
     116           0 :         for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
     117           0 :             delete fVariants[i];
     118             :         }
     119           0 :     }
     120             : 
     121             :     /**
     122             :      * Removes all mappings and makes 'other' point to the default value.
     123             :      */
     124           0 :     void clear() {
     125           0 :         *fVariants[0] = T();
     126           0 :         for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
     127           0 :             delete fVariants[i];
     128           0 :             fVariants[i] = NULL;
     129             :         }
     130           0 :     }
     131             : 
     132             :     /**
     133             :      * Iterates through the mappings in this instance, set index to NONE
     134             :      * prior to using. Call next repeatedly to get the values until it
     135             :      * returns NULL. Each time next returns, caller may pass index
     136             :      * to getCategoryName() to get the name of the plural category.
     137             :      * When this function returns NULL, index is CATEGORY_COUNT
     138             :      */
     139           0 :     const T *next(Category &index) const {
     140           0 :         int32_t idx = index;
     141           0 :         ++idx;
     142           0 :         for (; idx < UPRV_LENGTHOF(fVariants); ++idx) {
     143           0 :             if (fVariants[idx] != NULL) {
     144           0 :                 index = static_cast<Category>(idx);
     145           0 :                 return fVariants[idx];
     146             :             }
     147             :         }
     148           0 :         index = static_cast<Category>(idx);
     149           0 :         return NULL;
     150             :     }
     151             : 
     152             :     /**
     153             :      * non const version of next.
     154             :      */
     155           0 :     T *nextMutable(Category &index) {
     156           0 :         const T *result = next(index);
     157           0 :         return const_cast<T *>(result);
     158             :     }
     159             : 
     160             :     /**
     161             :      * Returns the 'other' variant.
     162             :      * Same as calling get(OTHER).
     163             :      */
     164           0 :     const T &getOther() const {
     165           0 :         return get(OTHER);
     166             :     }
     167             : 
     168             :     /**
     169             :      * Returns the value associated with a category.
     170             :      * If no value found, or v is NONE or CATEGORY_COUNT, falls
     171             :      * back to returning the value for the 'other' category.
     172             :      */
     173           0 :     const T &get(Category v) const {
     174           0 :         int32_t index = v;
     175           0 :         if (index < 0 || index >= UPRV_LENGTHOF(fVariants) || fVariants[index] == NULL) {
     176           0 :             return *fVariants[0];
     177             :         }
     178           0 :         return *fVariants[index];
     179             :     }
     180             : 
     181             :     /**
     182             :      * Convenience routine to get the value by category name. Otherwise
     183             :      * works just like get(Category).
     184             :      */
     185           0 :     const T &get(const char *category) const {
     186           0 :         return get(toCategory(category));
     187             :     }
     188             : 
     189             :     /**
     190             :      * Convenience routine to get the value by category name as a
     191             :      * UnicodeString. Otherwise works just like get(category).
     192             :      */
     193           0 :     const T &get(const UnicodeString &category) const {
     194           0 :         return get(toCategory(category));
     195             :     }
     196             : 
     197             :     /**
     198             :      * Returns a pointer to the value associated with a category
     199             :      * that caller can safely modify. If the value was defaulting to the 'other'
     200             :      * variant because no explicit value was stored, this method creates a
     201             :      * new value using the default constructor at the returned pointer.
     202             :      *
     203             :      * @param category the category with the value to change.
     204             :      * @param status error returned here if index is NONE or CATEGORY_COUNT
     205             :      *  or memory could not be allocated, or any other error happens.
     206             :      */
     207           0 :     T *getMutable(
     208             :             Category category,
     209             :             UErrorCode &status) {
     210           0 :         return getMutable(category, NULL, status);
     211             :     }
     212             : 
     213             :     /**
     214             :      * Convenience routine to get a mutable pointer to a value by category name.
     215             :      * Otherwise works just like getMutable(Category, UErrorCode &).
     216             :      * reports an error if the category name is invalid.
     217             :      */
     218           0 :     T *getMutable(
     219             :             const char *category,
     220             :             UErrorCode &status) {
     221           0 :         return getMutable(toCategory(category), NULL, status);
     222             :     }
     223             : 
     224             :     /**
     225             :      * Just like getMutable(Category, UErrorCode &) but copies defaultValue to
     226             :      * returned pointer if it was defaulting to the 'other' variant
     227             :      * because no explicit value was stored.
     228             :      */
     229           0 :     T *getMutableWithDefault(
     230             :             Category category,
     231             :             const T &defaultValue,
     232             :             UErrorCode &status) {
     233           0 :         return getMutable(category, &defaultValue, status);
     234             :     }
     235             : 
     236             :     /**
     237             :      * Returns TRUE if this object equals rhs.
     238             :      */
     239           0 :     UBool equals(
     240             :             const PluralMap<T> &rhs,
     241             :             UBool (*eqFunc)(const T &, const T &)) const {
     242           0 :         for (int32_t i = 0; i < UPRV_LENGTHOF(fVariants); ++i) {
     243           0 :             if (fVariants[i] == rhs.fVariants[i]) {
     244           0 :                 continue;
     245             :             }
     246           0 :             if (fVariants[i] == NULL || rhs.fVariants[i] == NULL) {
     247           0 :                 return FALSE;
     248             :             }
     249           0 :             if (!eqFunc(*fVariants[i], *rhs.fVariants[i])) {
     250           0 :                 return FALSE;
     251             :             }
     252             :         }
     253           0 :         return TRUE;
     254             :     }
     255             : 
     256             : private:
     257             :     T fOtherVariant;
     258             :     T* fVariants[6];
     259             : 
     260           0 :     T *getMutable(
     261             :             Category category,
     262             :             const T *defaultValue,
     263             :             UErrorCode &status) {
     264           0 :         if (U_FAILURE(status)) {
     265           0 :             return NULL;
     266             :         }
     267           0 :         int32_t index = category;
     268           0 :         if (index < 0 || index >= UPRV_LENGTHOF(fVariants)) {
     269           0 :             status = U_ILLEGAL_ARGUMENT_ERROR;
     270           0 :             return NULL;
     271             :         }
     272           0 :         if (fVariants[index] == NULL) {
     273           0 :             fVariants[index] = defaultValue == NULL ?
     274           0 :                     new T() : new T(*defaultValue);
     275             :         }
     276           0 :         if (!fVariants[index]) {
     277           0 :             status = U_MEMORY_ALLOCATION_ERROR;
     278             :         }
     279           0 :         return fVariants[index];
     280             :     }
     281             : 
     282           0 :     void initializeNew() {
     283           0 :         fVariants[0] = &fOtherVariant;
     284           0 :         for (int32_t i = 1; i < UPRV_LENGTHOF(fVariants); ++i) {
     285           0 :             fVariants[i] = NULL;
     286             :         }
     287           0 :     }
     288             : };
     289             : 
     290             : U_NAMESPACE_END
     291             : 
     292             : #endif

Generated by: LCOV version 1.13