Different take on pad() SFINAE, with overloads and only one enable_if<>. 14/head
authorJakob Petsovits <jpetso@topologyinc.com>
Fri, 15 Jan 2016 21:36:50 +0000 (16:36 -0500)
committerJakob Petsovits <jpetso@topologyinc.com>
Tue, 19 Jan 2016 20:58:41 +0000 (15:58 -0500)
Still breaks on VC14, but with fewer errors. Now we only have to
find a solution for one templated function instead of two.

cppcodec/detail/base32.hpp
cppcodec/detail/base64.hpp
cppcodec/detail/hex.hpp

index 6b9c2ef..4be4a4c 100644 (file)
@@ -47,26 +47,24 @@ public:
     static inline constexpr uint8_t binary_block_size() { return 5; }
     static inline constexpr uint8_t encoded_block_size() { return 8; }
 
-    template <typename Result, typename ResultState> static void encode_block(
-            Result& encoded, ResultState&, const uint8_t* src);
+    template <typename Result, typename ResultState>
+    static void encode_block(Result& encoded, ResultState&, const uint8_t* src);
 
-    template <typename Result, typename ResultState> static void encode_tail(
-            Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
+    template <typename Result, typename ResultState>
+    static void encode_tail(Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
 
-    template <typename Result, typename ResultState, typename V = CodecVariant> static void pad(
-            Result& encoded, ResultState&,
-            typename std::enable_if<V::generates_padding(), size_t>::type remaining_src_len);
+    template <typename Result, typename ResultState>
+    static void pad(Result&, ResultState&, ...) { } // lower priority overload
 
-    template <typename Result, typename ResultState, typename V = CodecVariant> static void pad(
-            Result&, ResultState&, typename std::enable_if<!V::generates_padding(), size_t>::type)
-    {
-    }
+    template <typename Result, typename ResultState, typename V = CodecVariant,
+            typename std::enable_if<V::generates_padding()>::type* = nullptr>
+    static void pad(Result& encoded, ResultState&, size_t remaining_src_len);
 
-    template <typename Result, typename ResultState> static void decode_block(
-            Result& decoded, ResultState&, const uint8_t* idx);
+    template <typename Result, typename ResultState>
+    static void decode_block(Result& decoded, ResultState&, const uint8_t* idx);
 
-    template <typename Result, typename ResultState> static void decode_tail(
-            Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
+    template <typename Result, typename ResultState>
+    static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
 };
 
 //
@@ -123,10 +121,10 @@ inline void base32<CodecVariant>::encode_tail(
 }
 
 template <typename CodecVariant>
-template <typename Result, typename ResultState, typename V>
+template <typename Result, typename ResultState, typename V,
+        typename std::enable_if<V::generates_padding()>::type*>
 inline void base32<CodecVariant>::pad(
-        Result& encoded, ResultState& state,
-        typename std::enable_if<V::generates_padding(), size_t>::type remaining_src_len)
+        Result& encoded, ResultState& state, size_t remaining_src_len)
 {
     switch (remaining_src_len) {
     case 1: // 2 symbols, 6 padding characters
index 99775c0..564ec3f 100644 (file)
@@ -45,26 +45,24 @@ public:
     static inline constexpr uint8_t binary_block_size() { return 3; }
     static inline constexpr uint8_t encoded_block_size() { return 4; }
 
-    template <typename Result, typename ResultState> static void encode_block(
-            Result& encoded, ResultState&, const uint8_t* src);
+    template <typename Result, typename ResultState>
+    static void encode_block(Result& encoded, ResultState&, const uint8_t* src);
 
-    template <typename Result, typename ResultState> static void encode_tail(
-            Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
+    template <typename Result, typename ResultState>
+    static void encode_tail(Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
 
-    template <typename Result, typename ResultState, typename V = CodecVariant> static void pad(
-            Result& encoded, ResultState&,
-            typename std::enable_if<V::generates_padding(), size_t>::type remaining_src_len);
+    template <typename Result, typename ResultState>
+    static void pad(Result&, ResultState&, ...) { } // lower priority overload
 
-    template <typename Result, typename ResultState, typename V = CodecVariant> static void pad(
-            Result&, ResultState&, typename std::enable_if<!V::generates_padding(), size_t>::type)
-    {
-    }
+    template <typename Result, typename ResultState, typename V = CodecVariant,
+            typename std::enable_if<V::generates_padding()>::type* = nullptr>
+    static void pad(Result& encoded, ResultState&, size_t remaining_src_len);
 
-    template <typename Result, typename ResultState> static void decode_block(
-            Result& decoded, ResultState&, const uint8_t* idx);
+    template <typename Result, typename ResultState>
+    static void decode_block(Result& decoded, ResultState&, const uint8_t* idx);
 
-    template <typename Result, typename ResultState> static void decode_tail(
-            Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
+    template <typename Result, typename ResultState>
+    static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
 };
 
 
@@ -101,10 +99,10 @@ inline void base64<CodecVariant>::encode_tail(
 }
 
 template <typename CodecVariant>
-template <typename Result, typename ResultState, typename V>
+template <typename Result, typename ResultState, typename V,
+        typename std::enable_if<V::generates_padding()>::type*>
 inline void base64<CodecVariant>::pad(
-        Result& encoded, ResultState& state,
-        typename std::enable_if<V::generates_padding(), size_t>::type remaining_src_len)
+        Result& encoded, ResultState& state, size_t remaining_src_len)
 {
     switch (remaining_src_len) {
     case 1: // 2 symbols, 2 padding characters
index 8d48494..892e189 100644 (file)
@@ -65,19 +65,20 @@ public:
     static inline constexpr uint8_t binary_block_size() { return 1; }
     static inline constexpr uint8_t encoded_block_size() { return 2; }
 
-    template <typename Result, typename ResultState> static void encode_block(
-            Result& encoded, ResultState&, const uint8_t* src);
+    template <typename Result, typename ResultState>
+    static void encode_block(Result& encoded, ResultState&, const uint8_t* src);
 
-    template <typename Result, typename ResultState> static void encode_tail(
-            Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
+    template <typename Result, typename ResultState>
+    static void encode_tail(Result& encoded, ResultState&, const uint8_t* src, size_t src_len);
 
-    template <typename Result, typename ResultState> static void pad(Result&, ResultState&, size_t) { }
+    template <typename Result, typename ResultState>
+    static void pad(Result&, ResultState&, size_t) { }
 
-    template <typename Result, typename ResultState> static void decode_block(
-            Result& decoded, ResultState&, const uint8_t* idx);
+    template <typename Result, typename ResultState>
+    static void decode_block(Result& decoded, ResultState&, const uint8_t* idx);
 
-    template <typename Result, typename ResultState> static void decode_tail(
-            Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
+    template <typename Result, typename ResultState>
+    static void decode_tail(Result& decoded, ResultState&, const uint8_t* idx, size_t idx_len);
 };