Bug 1289710 - Allow KTableEntry objects to be initialized with enum values of appropriate size. r=xidorn draft
authorCameron McCormack <cam@mcc.id.au>
Thu, 28 Jul 2016 15:40:09 +0800
changeset 393683 a79d94130c339c58f3c1055da68f118d1320ccf3
parent 392248 93d4bd8a4ad33d4202c8705e1a4e4fe716843614
child 393706 cd204987d4ef62443e26f6e076a7a3f7c0b3a514
child 393707 fccca38fee66bdb1d390c4d817b91b3c423bef0a
child 393710 26656e2a4db4b300ce6fc36cbb4db90f2f4d1251
push id24376
push userbmo:cam@mcc.id.au
push dateThu, 28 Jul 2016 07:40:28 +0000
reviewersxidorn
bugs1289710
milestone50.0a1
Bug 1289710 - Allow KTableEntry objects to be initialized with enum values of appropriate size. r=xidorn MozReview-Commit-ID: JluYrYmy5z1
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
widget/LookAndFeel.h
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1040,18 +1040,18 @@ const KTableEntry nsCSSProps::kBoxDecora
 };
 
 const KTableEntry nsCSSProps::kBoxShadowTypeKTable[] = {
   { eCSSKeyword_inset, NS_STYLE_BOX_SHADOW_INSET },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
 const KTableEntry nsCSSProps::kBoxSizingKTable[] = {
-  { eCSSKeyword_content_box,  uint8_t(StyleBoxSizing::Content) },
-  { eCSSKeyword_border_box,   uint8_t(StyleBoxSizing::Border) },
+  { eCSSKeyword_content_box,  StyleBoxSizing::Content },
+  { eCSSKeyword_border_box,   StyleBoxSizing::Border },
   { eCSSKeyword_UNKNOWN,      -1 }
 };
 
 const KTableEntry nsCSSProps::kCaptionSideKTable[] = {
   { eCSSKeyword_top,                  NS_STYLE_CAPTION_SIDE_TOP },
   { eCSSKeyword_right,                NS_STYLE_CAPTION_SIDE_RIGHT },
   { eCSSKeyword_bottom,               NS_STYLE_CAPTION_SIDE_BOTTOM },
   { eCSSKeyword_left,                 NS_STYLE_CAPTION_SIDE_LEFT },
@@ -2295,23 +2295,23 @@ const KTableEntry nsCSSProps::kDominantB
 
 const KTableEntry nsCSSProps::kFillRuleKTable[] = {
   { eCSSKeyword_nonzero, NS_STYLE_FILL_RULE_NONZERO },
   { eCSSKeyword_evenodd, NS_STYLE_FILL_RULE_EVENODD },
   { eCSSKeyword_UNKNOWN, -1 }
 };
 
 const KTableEntry nsCSSProps::kClipShapeSizingKTable[] = {
-  { eCSSKeyword_content_box,   uint8_t(StyleClipShapeSizing::Content) },
-  { eCSSKeyword_padding_box,   uint8_t(StyleClipShapeSizing::Padding) },
-  { eCSSKeyword_border_box,    uint8_t(StyleClipShapeSizing::Border) },
-  { eCSSKeyword_margin_box,    uint8_t(StyleClipShapeSizing::Margin) },
-  { eCSSKeyword_fill_box,      uint8_t(StyleClipShapeSizing::Fill) },
-  { eCSSKeyword_stroke_box,    uint8_t(StyleClipShapeSizing::Stroke) },
-  { eCSSKeyword_view_box,      uint8_t(StyleClipShapeSizing::View) },
+  { eCSSKeyword_content_box,   StyleClipShapeSizing::Content },
+  { eCSSKeyword_padding_box,   StyleClipShapeSizing::Padding },
+  { eCSSKeyword_border_box,    StyleClipShapeSizing::Border },
+  { eCSSKeyword_margin_box,    StyleClipShapeSizing::Margin },
+  { eCSSKeyword_fill_box,      StyleClipShapeSizing::Fill },
+  { eCSSKeyword_stroke_box,    StyleClipShapeSizing::Stroke },
+  { eCSSKeyword_view_box,      StyleClipShapeSizing::View },
   { eCSSKeyword_UNKNOWN,       -1 }
 };
 
 const KTableEntry nsCSSProps::kShapeRadiusKTable[] = {
   { eCSSKeyword_closest_side, NS_RADIUS_CLOSEST_SIDE },
   { eCSSKeyword_farthest_side, NS_RADIUS_FARTHEST_SIDE },
   { eCSSKeyword_UNKNOWN, -1 }
 };
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -6,16 +6,18 @@
 /*
  * methods for dealing with CSS properties and tables of the keyword
  * values they accept
  */
 
 #ifndef nsCSSProps_h___
 #define nsCSSProps_h___
 
+#include <limits>
+#include <type_traits>
 #include "nsString.h"
 #include "nsCSSProperty.h"
 #include "nsStyleStructFwd.h"
 #include "nsCSSKeywords.h"
 #include "mozilla/CSSEnabledState.h"
 #include "mozilla/UseCounter.h"
 
 // Length of the "--" prefix on custom names (such as custom property names,
@@ -324,21 +326,59 @@ enum nsStyleAnimType {
 
   // RefPtr<nsCSSShadowArray> values
   eStyleAnimType_Shadow,
 
   // property not animatable
   eStyleAnimType_None
 };
 
+namespace mozilla {
+
+// Type trait that determines whether the integral or enum type Type can fit
+// within the integral type Storage without loss.
+template<typename T, typename Storage>
+struct IsEnumFittingWithin
+  : IntegralConstant<
+      bool,
+      std::is_integral<Storage>::value &&
+      std::numeric_limits<typename std::underlying_type<T>::type>::min() >=
+        std::numeric_limits<Storage>::min() &&
+      std::numeric_limits<typename std::underlying_type<T>::type>::max() <=
+        std::numeric_limits<Storage>::max()
+    >
+{};
+
+} // namespace mozilla
+
 class nsCSSProps {
 public:
   typedef mozilla::CSSEnabledState EnabledState;
 
-  struct KTableEntry {
+  struct KTableEntry
+  {
+    // KTableEntry objects can be initialized either with an int16_t value
+    // or a value of an enumeration type that can fit within an int16_t.
+
+    KTableEntry(nsCSSKeyword aKeyword, int16_t aValue)
+      : mKeyword(aKeyword)
+      , mValue(aValue)
+    {
+    }
+
+    template<typename T,
+             typename = typename std::enable_if<std::is_enum<T>::value>::type>
+    KTableEntry(nsCSSKeyword aKeyword, T aValue)
+      : mKeyword(aKeyword)
+      , mValue(static_cast<int16_t>(aValue))
+    {
+      static_assert(mozilla::IsEnumFittingWithin<T, int16_t>::value,
+                    "aValue must be an enum that fits within mValue");
+    }
+
     nsCSSKeyword mKeyword;
     int16_t mValue;
   };
 
   static void AddRefTable(void);
   static void ReleaseTable(void);
 
   // Looks up the property with name aProperty and returns its corresponding
--- a/widget/LookAndFeel.h
+++ b/widget/LookAndFeel.h
@@ -24,17 +24,17 @@ struct LookAndFeelInt
 
 namespace mozilla {
 
 class LookAndFeel
 {
 public:
   // When modifying this list, also modify nsXPLookAndFeel::sColorPrefs
   // in widget/xpwidgts/nsXPLookAndFeel.cpp.
-  enum ColorID {
+  enum ColorID : uint8_t {
 
     // WARNING : NO NEGATIVE VALUE IN THIS ENUMERATION
     // see patch in bug 57757 for more information
 
     eColorID_WindowBackground,
     eColorID_WindowForeground,
     eColorID_WidgetBackground,
     eColorID_WidgetForeground,