You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@quickstep.apache.org by ji...@apache.org on 2017/04/03 22:01:35 UTC

[1/2] incubator-quickstep git commit: Template Metaprogramming facilities

Repository: incubator-quickstep
Updated Branches:
  refs/heads/new-op db611137e -> d70a6397d


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/TemplateUtil.hpp
----------------------------------------------------------------------
diff --git a/utility/TemplateUtil.hpp b/utility/TemplateUtil.hpp
index 869373f..587336d 100644
--- a/utility/TemplateUtil.hpp
+++ b/utility/TemplateUtil.hpp
@@ -30,384 +30,6 @@ namespace quickstep {
  *  @{
  */
 
-/**
- * @brief Represents a compile-time sequence of integers.
- *
- * Sequence is defined here for C++11 compatibility. For C++14 and above,
- * std::integer_sequence can be used to achieve the same functionality.
- *
- * TODO(jianqiao): directly use std::integer_sequence if having C++14 support.
- */
-template<std::size_t ...>
-struct Sequence {};
-
-/**
- * @brief The helper class for creating Sequence. MakeSequence<N>::type is
- *        equivalent to Sequence<1,2,...,N>.
- *
- * MakeSequence is defined here for C++11 compatibility. For C++14 and above,
- * std::make_index_sequence can be used to achieve the same functionality.
- *
- * TODO(jianqiao): directly use std::make_index_sequence if having C++14 support.
- */
-template<std::size_t N, std::size_t ...S>
-struct MakeSequence : MakeSequence<N-1, N-1, S...> {};
-
-template<std::size_t ...S>
-struct MakeSequence<0, S...> {
-  typedef Sequence<S...> type;
-};
-
-
-template <typename T, typename EnableT = void>
-struct IsTypeTrait {
-  static constexpr bool value = false;
-};
-
-template <typename T>
-struct IsTypeTrait<T, std::enable_if_t<
-    std::is_same<typename T::type, typename T::type>::value>> {
-  static constexpr bool value = true;
-};
-
-
-template<class...> struct Disjunction : std::false_type {};
-template<class B1> struct Disjunction<B1> : B1 {};
-template<class B1, class... Bn>
-struct Disjunction<B1, Bn...>
-    : std::conditional_t<bool(B1::value), B1, Disjunction<Bn...>>  {};
-
-template <typename check, typename ...cases>
-struct EqualsAny {
-  static constexpr bool value =
-      Disjunction<std::is_same<check, cases>...>::value;
-};
-
-template <char ...c>
-struct StringLiteral {
-  inline static std::string ToString() {
-    return std::string({c...});
-  }
-};
-
-template <typename LeftT, typename RightT>
-struct PairSelectorLeft {
-  typedef LeftT type;
-};
-
-template <typename LeftT, typename RightT>
-struct PairSelectorRight {
-  typedef RightT type;
-};
-
-/**
- * @brief Invoke the functor with the compile-time bool values wrapped as
- *        integral_constant types.
- */
-template <typename FunctorT, bool ...bool_values>
-inline auto InvokeOnBoolsInner(const FunctorT &functor) {
-  return functor(std::integral_constant<bool, bool_values>()...);
-}
-
-/**
- * @brief Recursive dispatching.
- */
-template <typename FunctorT, bool ...bool_values, typename ...Bools>
-inline auto InvokeOnBoolsInner(const FunctorT &functor,
-                               const bool tparam,
-                               const Bools ...rest_params) {
-  if (tparam) {
-    return InvokeOnBoolsInner<FunctorT, bool_values..., true>(
-        functor, rest_params...);
-  } else {
-    return InvokeOnBoolsInner<FunctorT, bool_values..., false>(
-        functor, rest_params...);
-  }
-}
-
-/**
- * @brief Move the functor to the first position in argument list.
- */
-template <std::size_t last, std::size_t ...i, typename TupleT>
-inline auto InvokeOnBoolsInner(TupleT &&args, Sequence<i...> &&indices) {
-  return InvokeOnBoolsInner(std::get<last>(std::forward<TupleT>(args)),
-                            std::get<i>(std::forward<TupleT>(args))...);
-}
-
-template <typename Out, typename Rest,
-          template <typename> class Op, typename EnableT = void>
-struct MapInner;
-
-template <typename Out, typename Rest,
-          template <typename> class Op, typename EnableT = void>
-struct FlatMapInner;
-
-template <typename Out, typename Rest,
-          template <typename> class Op, typename EnableT = void>
-struct FilterInner;
-
-template <typename Out, typename Rest,
-          template <typename> class Op, typename EnableT = void>
-struct FilterMapInner;
-
-template <typename Out, typename Rest, typename EnableT = void>
-struct UniqueInner;
-
-template <typename Out, typename Rest, typename ...DumbT>
-struct UniqueInnerHelper {
-  using type = typename UniqueInner<Out, Rest>::type;
-  static constexpr bool kDumbSize = sizeof...(DumbT);
-};
-
-template <typename Out, typename Rest,
-          typename Subtrahend, typename EnableT = void>
-struct SubtractInner;
-
-template <typename ...Ts>
-class TypeList;
-
-template <typename ...Ts>
-class TypeListCommon {
- private:
-  template <typename ...Tail>
-  struct AppendInner {
-    using type = TypeList<Ts..., Tail...>;
-  };
-
- public:
-  static constexpr std::size_t length = sizeof...(Ts);
-
-  template <template <typename ...> class Target>
-  using bind = Target<Ts...>;
-
-  template <typename T>
-  using push_front = TypeList<T, Ts...>;
-
-  template <typename T>
-  using push_back = TypeList<Ts..., T>;
-
-  template <typename T>
-  using contains = EqualsAny<T, Ts...>;
-
-  template <typename TL>
-  using append = typename TL::template bind<AppendInner>::type;
-
-  template <template <typename> class Op>
-  using map = typename MapInner<TypeList<>, TypeList<Ts...>, Op>::type;
-
-  template <template <typename> class Op>
-  using flatmap = typename FlatMapInner<TypeList<>, TypeList<Ts...>, Op>::type;
-
-  template <template <typename> class Op>
-  using filter = typename FilterInner<TypeList<>, TypeList<Ts...>, Op>::type;
-
-  template <template <typename> class Op>
-  using filtermap = typename FilterMapInner<TypeList<>, TypeList<Ts...>, Op>::type;
-
-  template <typename ...DumbT>
-  using unique = typename UniqueInnerHelper<TypeList<>, TypeList<Ts...>, DumbT...>::type;
-
-  template <typename Subtrahend>
-  using subtract = typename SubtractInner<TypeList<>, TypeList<Ts...>, Subtrahend>::type;
-};
-
-/**
- * @brief A helper function for bool branched template specialization.
- *
- * Usage example:
- * --
- * bool c1 = true, c2 = false;
- *
- * InvokeOnBools(
- *     c1, c2,
- *     [&](auto c1, auto c2) -> SomeBaseClass* {
- *   using T1 = decltype(c1);  // T1 == std::true_type
- *   using T2 = decltype(c2);  // T2 == std::false_type
- *
- *   constexpr bool cv1 = T1::value;  // cv1 == true
- *   constexpr bool cv2 = T2::value;  // cv2 == false
- *
- *   SomeFunction<cv1, cv2>(...);
- *   return new SomeClass<cv1, cv2>(...);
- * });
- * --
- */
-template <typename ...ArgTypes>
-inline auto InvokeOnBools(ArgTypes ...args) {
-  constexpr std::size_t last = sizeof...(args) - 1;
-  return InvokeOnBoolsInner<last>(
-      std::forward_as_tuple(args...),
-      typename MakeSequence<last>::type());
-}
-
-template <typename ...Ts>
-class TypeList : public TypeListCommon<Ts...> {
- private:
-  template <typename Head, typename ...Tail>
-  struct HeadTailInner {
-    using head = Head;
-    using tail = TypeList<Tail...>;
-  };
-
- public:
-  using head = typename HeadTailInner<Ts...>::head;
-  using tail = typename HeadTailInner<Ts...>::tail;
-};
-
-template <>
-class TypeList<> : public TypeListCommon<> {
-};
-
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct MapInner<Out, Rest, Op,
-                std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct MapInner<Out, Rest, Op,
-                std::enable_if_t<Rest::length != 0>>
-    : MapInner<typename Out::template push_back<typename Op<typename Rest::head>::type>,
-               typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FlatMapInner<Out, Rest, Op,
-                    std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FlatMapInner<Out, Rest, Op,
-                    std::enable_if_t<Rest::length != 0>>
-    : FlatMapInner<typename Out::template append<typename Op<typename Rest::head>::type>,
-                   typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterInner<Out, Rest, Op,
-                   std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterInner<Out, Rest, Op,
-                   std::enable_if_t<Op<typename Rest::head>::value>>
-    : FilterInner<typename Out::template push_back<typename Rest::head>,
-                  typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterInner<Out, Rest, Op,
-                   std::enable_if_t<!Op<typename Rest::head>::value>>
-    : FilterInner<Out, typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterMapInner<Out, Rest, Op,
-                      std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterMapInner<Out, Rest, Op,
-                      std::enable_if_t<Rest::length != 0 &&
-                                       IsTypeTrait<Op<typename Rest::head>>::value>>
-    : FilterMapInner<typename Out::template push_back<typename Op<typename Rest::head>::type>,
-                     typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest, template <typename> class Op>
-struct FilterMapInner<Out, Rest, Op,
-                      std::enable_if_t<Rest::length != 0 &&
-                                       !IsTypeTrait<Op<typename Rest::head>>::value>>
-    : FilterMapInner<Out, typename Rest::tail, Op> {};
-
-template <typename Out, typename Rest>
-struct UniqueInner<Out, Rest,
-                   std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest>
-struct UniqueInner<Out, Rest,
-                   std::enable_if_t<Out::template contains<typename Rest::head>::value>>
-    : UniqueInner<Out, typename Rest::tail> {};
-
-template <typename Out, typename Rest>
-struct UniqueInner<Out, Rest,
-                   std::enable_if_t<!Out::template contains<typename Rest::head>::value>>
-    : UniqueInner<typename Out::template push_back<typename Rest::head>,
-                  typename Rest::tail> {};
-
-template <typename Out, typename Rest, typename Subtrahend>
-struct SubtractInner<Out, Rest, Subtrahend,
-                     std::enable_if_t<Rest::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename Rest, typename Subtrahend>
-struct SubtractInner<Out, Rest, Subtrahend,
-                     std::enable_if_t<Subtrahend::template contains<
-                         typename Rest::head>::value>>
-    : SubtractInner<Out, typename Rest::tail, Subtrahend> {};
-
-template <typename Out, typename Rest, typename Subtrahend>
-struct SubtractInner<Out, Rest, Subtrahend,
-                     std::enable_if_t<!Subtrahend::template contains<
-                         typename Rest::head>::value>>
-    : SubtractInner<typename Out::template push_back<typename Rest::head>,
-                    typename Rest::tail, Subtrahend> {};
-
-template <typename LeftEdge, typename RightEdge, typename EnableT = void>
-struct EdgeMatcher {};
-
-template <typename LeftEdge, typename RightEdge>
-struct EdgeMatcher<LeftEdge, RightEdge,
-                   std::enable_if_t<std::is_same<typename LeftEdge::tail::head,
-                                                 typename RightEdge::head>::value>> {
-  using type = TypeList<typename LeftEdge::head, typename RightEdge::tail::head>;
-};
-
-template <typename LeftEdges, typename RightEdges>
-struct JoinPath {
-  template <typename LeftEdge>
-  struct JoinPathLeftHelper {
-    template <typename RightEdge>
-    struct JoinPathRightHelper : EdgeMatcher<LeftEdge, RightEdge> {};
-
-    using type = typename RightEdges::template filtermap<JoinPathRightHelper>;
-  };
-  using type = typename LeftEdges::template flatmap<JoinPathLeftHelper>;
-};
-
-// Semi-naive
-template <typename Out, typename WorkSet, typename Edges, typename EnableT = void>
-struct TransitiveClosureInner;
-
-template <typename Out, typename WorkSet, typename Edges>
-struct TransitiveClosureInner<Out, WorkSet, Edges,
-                              std::enable_if_t<WorkSet::length == 0>> {
-  using type = Out;
-};
-
-template <typename Out, typename WorkSet, typename Edges>
-struct TransitiveClosureInner<Out, WorkSet, Edges,
-                              std::enable_if_t<WorkSet::length != 0>>
-    : TransitiveClosureInner<typename Out::template append<WorkSet>,
-                             typename JoinPath<WorkSet, Edges>::type::template subtract<
-                                 typename Out::template append<WorkSet>>::template unique<>,
-                             Edges> {};
-
-template <typename Edge>
-struct TransitiveClosureInitializer {
-  using type = TypeList<TypeList<typename Edge::head, typename Edge::head>,
-                        TypeList<typename Edge::tail::head, typename Edge::tail::head>>;
-};
-
-template <typename Edges>
-using TransitiveClosure =
-    typename TransitiveClosureInner<
-        TypeList<>,
-        typename Edges::template flatmap<TransitiveClosureInitializer>::template unique<>,
-        Edges>::type;
-
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/meta/CMakeLists.txt b/utility/meta/CMakeLists.txt
new file mode 100644
index 0000000..1b72dd9
--- /dev/null
+++ b/utility/meta/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Declare micro-libs:
+add_library(quickstep_utility_meta_Common ../../empty_src.cpp Common.hpp)
+add_library(quickstep_utility_meta_Dispatchers ../../empty_src.cpp Dispatchers.hpp)
+add_library(quickstep_utility_meta_TMP ../../empty_src.cpp TMP.hpp)
+add_library(quickstep_utility_meta_TransitiveClosure ../../empty_src.cpp TransitiveClosure.hpp)
+add_library(quickstep_utility_meta_TypeList ../../empty_src.cpp TypeList.hpp)
+add_library(quickstep_utility_meta_TypeListMetaFunctions ../../empty_src.cpp TypeListMetaFunctions.hpp)
+
+# Link dependencies:
+target_link_libraries(quickstep_utility_meta_Dispatchers
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_utility_meta_TMP
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_Dispatchers
+                      quickstep_utility_meta_TransitiveClosure
+                      quickstep_utility_meta_TypeList)
+target_link_libraries(quickstep_utility_meta_TransitiveClosure
+                      quickstep_utility_meta_TypeList)
+target_link_libraries(quickstep_utility_meta_TypeList
+                      quickstep_utility_meta_Common
+                      quickstep_utility_meta_TypeListMetaFunctions)
+target_link_libraries(quickstep_utility_meta_TypeListMetaFunctions
+                      quickstep_utility_meta_Common)
+

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/Common.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp
new file mode 100644
index 0000000..39c513e
--- /dev/null
+++ b/utility/meta/Common.hpp
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_COMMON_HPP_
+#define QUICKSTEP_UTILITY_META_COMMON_HPP_
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename T, T ...s>
+struct Sequence {
+  template <template <typename ...> class Host>
+  using bind_to = Host<std::integral_constant<T, s>...>;
+
+  template <template <T ...> class Host>
+  using bind_values_to = Host<s...>;
+
+  template <typename U>
+  using cast_to = Sequence<U, static_cast<U>(s)...>;
+
+  template <typename CollectionT>
+  inline static CollectionT Instantiate() {
+    return { s... };
+  }
+};
+
+template <std::size_t ...s>
+using IntegerSequence = Sequence<std::size_t, s...>;
+
+
+template <std::size_t n, std::size_t ...s>
+struct MakeSequence : MakeSequence<n-1, n-1, s...> {};
+
+template <std::size_t ...s>
+struct MakeSequence<0, s...> {
+  using type = IntegerSequence<s...>;
+};
+
+
+template <typename ...> struct Conjunction : std::true_type {};
+template <typename B> struct Conjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Conjunction<B, Bs...>
+    : std::conditional_t<B::value, Conjunction<Bs...>, B> {};
+
+template <typename ...> struct Disjunction : std::false_type {};
+template <typename B> struct Disjunction<B> : B {};
+template <typename B, typename ...Bs>
+struct Disjunction<B, Bs...>
+    : std::conditional_t<B::value, B, Disjunction<Bs...>> {};
+
+template <typename check, typename ...cases>
+struct EqualsAny {
+  static constexpr bool value =
+     Disjunction<std::is_same<check, cases>...>::value;
+};
+
+
+template <typename T, typename Enable = void>
+struct IsTrait {
+  static constexpr bool value = false;
+};
+
+template <typename T>
+struct IsTrait<T, std::enable_if_t<
+    std::is_same<typename T::type, typename T::type>::value>> {
+  static constexpr bool value = true;
+};
+
+template <typename T, template <typename> class Op, typename Enable = void>
+struct IsWellFormed {
+  static constexpr bool value = false;
+};
+
+template <typename T, template <typename> class Op>
+struct IsWellFormed<T, Op, std::enable_if_t<std::is_same<Op<T>, Op<T>>::value>> {
+  static constexpr bool value = true;
+};
+
+
+template <typename LeftT, typename RightT>
+struct PairSelectorLeft {
+  typedef LeftT type;
+};
+
+template <typename LeftT, typename RightT>
+struct PairSelectorRight {
+  typedef RightT type;
+};
+
+
+template <char ...c>
+struct StringLiteral {
+  inline static std::string ToString() {
+    return std::string({c...});
+  }
+};
+
+template <template <typename ...> class Op>
+class TraitWrapper {
+ private:
+  template <typename ...ArgTypes>
+  struct Implemenation {
+    using type = Op<ArgTypes...>;
+  };
+
+ public:
+  template <typename ...ArgTypes>
+  using type = Implemenation<ArgTypes...>;
+};
+
+template <template <typename ...> class Op>
+struct TraitUnwrapper {
+  template <typename ...ArgTypes>
+  using type = typename Op<ArgTypes...>::type;
+};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_COMMON_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/Dispatchers.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/Dispatchers.hpp b/utility/meta/Dispatchers.hpp
new file mode 100644
index 0000000..5b0ee48
--- /dev/null
+++ b/utility/meta/Dispatchers.hpp
@@ -0,0 +1,107 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_DISPATCHERS_HPP_
+#define QUICKSTEP_UTILITY_META_DISPATCHERS_HPP_
+
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+/**
+ * @brief A helper function for bool branched template specialization.
+ *
+ * Usage example:
+ * --
+ * bool c1 = true, c2 = false;
+ *
+ * InvokeOnBools(
+ *     c1, c2,
+ *     [&](auto c1, auto c2) -> SomeBaseClass* {
+ *   using T1 = decltype(c1);  // T1 == std::true_type
+ *   using T2 = decltype(c2);  // T2 == std::false_type
+ *
+ *   constexpr bool cv1 = T1::value;  // cv1 == true
+ *   constexpr bool cv2 = T2::value;  // cv2 == false
+ *
+ *   SomeFunction<cv1, cv2>(...);
+ *   return new SomeClass<cv1, cv2>(...);
+ * });
+ * --
+ */
+template <typename ...ArgTypes>
+inline auto InvokeOnBools(ArgTypes ...args);
+
+
+namespace internal {
+
+/**
+ * @brief Invoke the functor with the compile-time bool values wrapped as
+ *        integral_constant types.
+ */
+template <typename FunctorT, bool ...bool_values>
+inline auto InvokeOnBoolsInner(const FunctorT &functor) {
+  return functor(std::integral_constant<bool, bool_values>()...);
+}
+
+/**
+ * @brief Recursive dispatching.
+ */
+template <typename FunctorT, bool ...bool_values, typename ...Bools>
+inline auto InvokeOnBoolsInner(const FunctorT &functor,
+                               const bool tparam,
+                               const Bools ...rest_params) {
+  if (tparam) {
+    return InvokeOnBoolsInner<FunctorT, bool_values..., true>(
+        functor, rest_params...);
+  } else {
+    return InvokeOnBoolsInner<FunctorT, bool_values..., false>(
+        functor, rest_params...);
+  }
+}
+
+/**
+ * @brief Move the functor to the first position in argument list.
+ */
+template <std::size_t last, std::size_t ...i, typename TupleT>
+inline auto InvokeOnBoolsInner(TupleT &&args, IntegerSequence<i...> &&indices) {
+  return InvokeOnBoolsInner(std::get<last>(std::forward<TupleT>(args)),
+                            std::get<i>(std::forward<TupleT>(args))...);
+}
+
+}  // namespace internal
+
+template <typename ...ArgTypes>
+inline auto InvokeOnBools(ArgTypes ...args) {
+  constexpr std::size_t last = sizeof...(args) - 1;
+  return internal::InvokeOnBoolsInner<last>(std::forward_as_tuple(args...),
+                                            typename MakeSequence<last>::type());
+}
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_DISPATCHERS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/TMP.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TMP.hpp b/utility/meta/TMP.hpp
new file mode 100644
index 0000000..5456479
--- /dev/null
+++ b/utility/meta/TMP.hpp
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_TMP_HPP_
+#define QUICKSTEP_UTILITY_META_TMP_HPP_
+
+#include "utility/meta/Common.hpp"
+#include "utility/meta/Dispatchers.hpp"
+#include "utility/meta/TransitiveClosure.hpp"
+#include "utility/meta/TypeList.hpp"
+
+#endif  // QUICKSTEP_UTILITY_META_TMP_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/TransitiveClosure.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TransitiveClosure.hpp b/utility/meta/TransitiveClosure.hpp
new file mode 100644
index 0000000..a5362bb
--- /dev/null
+++ b/utility/meta/TransitiveClosure.hpp
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_TRANSITIVE_CLOSURE_HPP_
+#define QUICKSTEP_UTILITY_META_TRANSITIVE_CLOSURE_HPP_
+
+#include "utility/meta/TypeList.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename Edges>
+struct TransitiveClosure;
+
+
+namespace internal {
+
+template <typename TL, typename Enable = void>
+struct EdgeMatcher {};
+
+template <typename TL>
+struct EdgeMatcher<
+    TL,
+    std::enable_if_t<std::is_same<typename TL::template at<0, 1>,
+                                  typename TL::template at<1, 0>>::value>> {
+  using type = TypeList<typename TL::template at<0, 0>,
+                        typename TL::template at<1, 1>>;
+};
+
+template <typename LeftEdges, typename RightEdges>
+struct JoinPath {
+  using type = typename LeftEdges::template cartesian_product<RightEdges>
+                                 ::template filtermap<EdgeMatcher>;
+};
+
+// Semi-naive
+template <typename Out, typename WorkSet, typename Edges, typename Enable = void>
+struct TransitiveClosureInner;
+
+template <typename Out, typename WorkSet, typename Edges>
+struct TransitiveClosureInner<Out, WorkSet, Edges,
+                              std::enable_if_t<WorkSet::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename WorkSet, typename Edges>
+struct TransitiveClosureInner<Out, WorkSet, Edges,
+                              std::enable_if_t<WorkSet::length != 0>>
+    : TransitiveClosureInner<typename Out::template append<WorkSet>,
+                             typename JoinPath<WorkSet, Edges>::type::template subtract<
+                                 typename Out::template append<WorkSet>>::template unique<>,
+                             Edges> {};
+
+template <typename Edge>
+struct TransitiveClosureInitializer {
+  using type = TypeList<TypeList<typename Edge::head, typename Edge::head>,
+                        TypeList<typename Edge::tail::head, typename Edge::tail::head>>;
+};
+
+template <typename Edges>
+using TransitiveClosureHelper =
+    typename TransitiveClosureInner<TypeList<>,
+                                    typename Edges::template flatmap<
+                                        TransitiveClosureInitializer>::template unique<>,
+                                    Edges>::type;
+
+}  // namespace internal
+
+template <typename Edges>
+struct TransitiveClosure : internal::TransitiveClosureHelper<Edges> {};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TRANSITIVE_CLOSURE_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/TypeList.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp
new file mode 100644
index 0000000..9257173
--- /dev/null
+++ b/utility/meta/TypeList.hpp
@@ -0,0 +1,124 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_TYPE_LIST_HPP_
+#define QUICKSTEP_UTILITY_META_TYPE_LIST_HPP_
+
+#include "utility/meta/Common.hpp"
+#include "utility/meta/TypeListMetaFunctions.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename ...Ts>
+class TypeList;
+
+template <typename ...Ts>
+class TypeListCommon {
+ private:
+  template <typename ...Tail> struct AppendHelper {
+    using type = TypeList<Ts..., Tail...>;
+  };
+
+ public:
+  static constexpr std::size_t length = sizeof...(Ts);
+
+  using type = TypeList<Ts...>;
+
+  template <template <typename ...> class Host>
+  using bind_to = Host<Ts...>;
+
+  template <std::size_t ...pos>
+  using at = typename internal::ElementAtImpl<
+      TypeList<Ts...>, TypeList<std::integral_constant<std::size_t, pos>...>>::type;
+
+  template <typename T>
+  using push_front = TypeList<T, Ts...>;
+
+  template <typename T>
+  using push_back = TypeList<Ts..., T>;
+
+  template <typename T>
+  using contains = EqualsAny<T, Ts...>;
+
+  template <typename ...DumbT>
+  using unique = typename internal::UniqueImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+
+  template <typename TL>
+  using append = typename TL::template bind_to<AppendHelper>::type;
+
+  template <typename TL>
+  using cartesian_product = typename internal::CartesianProductImpl<TypeList<Ts...>, TL>::type;
+
+  template <typename Subtrahend>
+  using subtract = typename internal::SubtractImpl<TypeList<>, TypeList<Ts...>, Subtrahend>::type;
+
+  template <template <typename ...> class Op>
+  using map = TypeList<typename Op<Ts>::type...>;
+
+  template <template <typename ...> class Op>
+  using flatmap = typename internal::FlatmapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <template <typename ...> class Op>
+  using filter = typename internal::FilterImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <template <typename ...> class Op>
+  using filtermap = typename internal::FiltermapImpl<TypeList<>, TypeList<Ts...>, Op>::type;
+
+  template <typename ...DumbT>
+  using flatten_once = typename internal::FlattenOnceImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type;
+
+  template <typename TL>
+  using zip = typename internal::ZipImpl<TypeList<>, TypeList<Ts...>, TL>::type;
+
+  template <typename TL, template <typename ...> class Op>
+  using zip_with = typename internal::ZipWithImpl<TypeList<>, TypeList<Ts...>, TL, Op>::type;
+
+  template <typename T>
+  using as_sequence = typename internal::AsSequenceImpl<T>::type;
+};
+
+template <typename ...Ts>
+class TypeList : public TypeListCommon<Ts...> {
+ private:
+  template <typename Head, typename ...Tail>
+  struct HeadTailHelper {
+    using head = Head;
+    using tail = TypeList<Tail...>;
+  };
+
+ public:
+  using head = typename HeadTailHelper<Ts...>::head;
+  using tail = typename HeadTailHelper<Ts...>::tail;
+};
+
+template <>
+class TypeList<> : public TypeListCommon<> {
+};
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TYPE_LIST_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/meta/TypeListMetaFunctions.hpp
----------------------------------------------------------------------
diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp
new file mode 100644
index 0000000..d908493
--- /dev/null
+++ b/utility/meta/TypeListMetaFunctions.hpp
@@ -0,0 +1,245 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_
+#define QUICKSTEP_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_
+
+#include "utility/meta/Common.hpp"
+
+namespace quickstep {
+namespace meta {
+
+/** \addtogroup Utility
+ *  @{
+ */
+
+template <typename ...Ts>
+class TypeList;
+
+namespace internal {
+
+template <typename TL, typename PosTL, typename Enable = void>
+struct ElementAtImpl;
+
+template <typename TL, typename PosTL>
+struct ElementAtImpl<TL, PosTL,
+                     std::enable_if_t<PosTL::length == 0>> {
+  using type = TL;
+};
+
+template <typename TL, typename PosTL>
+struct ElementAtImpl<TL, PosTL,
+                     std::enable_if_t<PosTL::length != 0>>
+    : ElementAtImpl<typename std::tuple_element<
+                        PosTL::head::value,
+                        typename TL::template bind_to<std::tuple>>::type,
+                    typename PosTL::tail> {};
+
+
+template <typename Out, typename Rest, typename Enable = void>
+struct UniqueImpl;
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<Out::template contains<typename Rest::head>::value>>
+    : UniqueImpl<Out, typename Rest::tail> {};
+
+template <typename Out, typename Rest>
+struct UniqueImpl<Out, Rest,
+                  std::enable_if_t<!Out::template contains<typename Rest::head>::value>>
+    : UniqueImpl<typename Out::template push_back<typename Rest::head>,
+                 typename Rest::tail> {};
+
+
+template <typename Out, typename Rest, typename Subtrahend, typename Enable = void>
+struct SubtractImpl;
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<Subtrahend::template contains<
+                        typename Rest::head>::value>>
+    : SubtractImpl<Out, typename Rest::tail, Subtrahend> {};
+
+template <typename Out, typename Rest, typename Subtrahend>
+struct SubtractImpl<Out, Rest, Subtrahend,
+                    std::enable_if_t<!Subtrahend::template contains<
+                        typename Rest::head>::value>>
+    : SubtractImpl<typename Out::template push_back<typename Rest::head>,
+                   typename Rest::tail, Subtrahend> {};
+
+
+template <typename LeftTL, typename RightTL>
+struct CartesianProductImpl {
+  template <typename LeftT>
+  struct LeftHelper {
+    template <typename RightT>
+    struct RightHelper {
+      using type = TypeList<LeftT, RightT>;
+    };
+    using type = typename RightTL::template map<RightHelper>;
+  };
+  using type = typename LeftTL::template flatmap<LeftHelper>;
+};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FlatmapImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FlatmapImpl<Out, Rest, Op,
+                   std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FlatmapImpl<Out, Rest, Op,
+                   std::enable_if_t<Rest::length != 0>>
+    : FlatmapImpl<typename Out::template append<typename Op<typename Rest::head>::type>,
+                  typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FilterImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<Op<typename Rest::head>::value>>
+    : FilterImpl<typename Out::template push_back<typename Rest::head>,
+                 typename Rest::tail, Op> {};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FilterImpl<Out, Rest, Op,
+                  std::enable_if_t<!Op<typename Rest::head>::value>>
+    : FilterImpl<Out, typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, template <typename ...> class Op,
+          typename Enable = void>
+struct FiltermapImpl;
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length != 0 &&
+                                      IsTrait<Op<typename Rest::head>>::value>>
+    : FiltermapImpl<typename Out::template push_back<typename Op<typename Rest::head>::type>,
+                    typename Rest::tail, Op> {};
+
+template <typename Out, typename Rest, template <typename ...> class Op>
+struct FiltermapImpl<Out, Rest, Op,
+                     std::enable_if_t<Rest::length != 0 &&
+                                      !IsTrait<Op<typename Rest::head>>::value>>
+    : FiltermapImpl<Out, typename Rest::tail, Op> {};
+
+
+template <typename Out, typename Rest, typename Enable = void>
+struct FlattenOnceImpl;
+
+template <typename Out, typename Rest>
+struct FlattenOnceImpl<Out, Rest,
+                       std::enable_if_t<Rest::length == 0>> {
+  using type = Out;
+};
+
+template <typename Out, typename Rest>
+struct FlattenOnceImpl<Out, Rest,
+                       std::enable_if_t<Rest::length != 0>>
+    : FlattenOnceImpl<typename Out::template append<typename Rest::head>,
+                      typename Rest::tail> {};
+
+
+template <typename Out, typename RestL, typename RestR, typename Enable = void>
+struct ZipImpl;
+
+template <typename Out, typename RestL, typename RestR>
+struct ZipImpl<Out, RestL, RestR,
+               std::enable_if_t<RestL::length == 0 || RestR::length == 0>> {
+  static_assert(RestL::length == 0 && RestR::length == 0,
+                "Zip failed: TypeLists have unequal lengths");
+  using type = Out;
+};
+
+template <typename Out, typename RestL, typename RestR>
+struct ZipImpl<Out, RestL, RestR,
+               std::enable_if_t<RestL::length != 0 && RestR::length != 0>>
+    : ZipImpl<typename Out::template push_back<
+                  TypeList<typename RestL::head, typename RestR::head>>,
+              typename RestL::tail, typename RestR::tail> {};
+
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op, typename Enable = void>
+struct ZipWithImpl;
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op>
+struct ZipWithImpl<Out, RestL, RestR, Op,
+                   std::enable_if_t<RestL::length == 0 || RestR::length == 0>> {
+  static_assert(RestL::length == 0 && RestR::length == 0,
+                "ZipWith failed: TypeLists have unequal lengths");
+  using type = Out;
+};
+
+template <typename Out, typename RestL, typename RestR,
+          template <typename ...> class Op>
+struct ZipWithImpl<Out, RestL, RestR, Op,
+                   std::enable_if_t<RestL::length != 0 && RestR::length != 0>>
+    : ZipWithImpl<typename Out::template push_back<
+                      typename Op<typename RestL::head, typename RestR::head>::type>,
+                  typename RestL::tail, typename RestR::tail, Op> {};
+
+
+template <typename T, typename ...Ts>
+struct AsSequenceImpl {
+  using type = Sequence<T, static_cast<T>(Ts::value)...>;
+};
+
+}  // namespace internal
+
+/** @} */
+
+}  // namespace meta
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_UTILITY_META_TYPE_LIST_META_FUNCTIONS_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/tests/TemplateUtil_unittest.cpp
----------------------------------------------------------------------
diff --git a/utility/tests/TemplateUtil_unittest.cpp b/utility/tests/TemplateUtil_unittest.cpp
deleted file mode 100644
index ce5d662..0000000
--- a/utility/tests/TemplateUtil_unittest.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- **/
-
-#include "utility/TemplateUtil.hpp"
-
-#include <memory>
-#include <string>
-#include <sstream>
-#include <tuple>
-#include <utility>
-
-#include "utility/Macros.hpp"
-
-#include "gtest/gtest.h"
-
-namespace quickstep {
-
-class SomeArgType {
- public:
-  explicit SomeArgType(const std::string &value)
-      : value_(value) {
-  }
-
-  SomeArgType(SomeArgType &&arg)
-      : value_(std::move(arg.value_)) {
-  }
-
-  std::string toString() const {
-    return value_;
-  }
-
- private:
-  const std::string value_;
-
-  DISALLOW_COPY_AND_ASSIGN(SomeArgType);
-};
-
-class BaseClass {
- public:
-  virtual std::string toString() const = 0;
-};
-
-template <bool c1, bool c2, bool c3, bool c4, bool c5, bool c6>
-class SomeClass : public BaseClass {
- public:
-  SomeClass(const int a1, SomeArgType &&a2)
-      : a1_(a1), a2_(std::forward<SomeArgType>(a2)) {
-  }
-
-  std::string toString() const override {
-    std::ostringstream oss;
-    oss << "{ ";
-    if (c1) {
-      oss << "c1 ";
-    }
-    if (c2) {
-      oss << "c2 ";
-    }
-    if (c3) {
-      oss << "c3 ";
-    }
-    if (c4) {
-      oss << "c4 ";
-    }
-    if (c5) {
-      oss << "c5 ";
-    }
-    if (c6) {
-      oss << "c6 ";
-    }
-    oss << "} " << a1_ << " " << a2_.toString();
-    return oss.str();
-  }
-
- private:
-  const int a1_;
-  const SomeArgType a2_;
-};
-
-void RunTest(const bool c1, const bool c2, const bool c3,
-             const bool c4, const bool c5, const bool c6,
-             const std::string &expected) {
-  // arg should be perfectly forwarded.
-  SomeArgType arg("xyz");
-
-  std::unique_ptr<BaseClass> base(
-      CreateBoolInstantiatedInstance<SomeClass, BaseClass>(std::forward_as_tuple(10, std::move(arg)),
-                                                           c1, c2, c3, c4, c5, c6));
-  EXPECT_STREQ(expected.c_str(), base->toString().c_str());
-}
-
-TEST(TemplateUtilTest, TemplateUtilTest) {
-  RunTest(true, false, true, false, true, false, "{ c1 c3 c5 } 10 xyz");
-  RunTest(true, true, true, true, true, true, "{ c1 c2 c3 c4 c5 c6 } 10 xyz");
-  RunTest(false, false, true, true, false, false, "{ c3 c4 } 10 xyz");
-  RunTest(false, false, false, false, false, false, "{ } 10 xyz");
-}
-
-}  // namespace quickstep



[2/2] incubator-quickstep git commit: Template Metaprogramming facilities

Posted by ji...@apache.org.
Template Metaprogramming facilities


Project: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/commit/d70a6397
Tree: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/tree/d70a6397
Diff: http://git-wip-us.apache.org/repos/asf/incubator-quickstep/diff/d70a6397

Branch: refs/heads/new-op
Commit: d70a6397d8cd6c29b68f83971e34886d701f1c25
Parents: db61113
Author: Jianqiao Zhu <ji...@cs.wisc.edu>
Authored: Mon Apr 3 17:01:16 2017 -0500
Committer: Jianqiao Zhu <ji...@cs.wisc.edu>
Committed: Mon Apr 3 17:01:16 2017 -0500

----------------------------------------------------------------------
 storage/CMakeLists.txt                          |   2 +-
 storage/PackedPayloadHashTable.cpp              |   4 +-
 types/AsciiStringSuperType.hpp                  |  11 +-
 types/CMakeLists.txt                            |  39 +-
 types/CharType.hpp                              |   6 +-
 types/DateType.hpp                              |   8 +-
 types/DatetimeIntervalType.hpp                  |  11 +-
 types/DatetimeType.hpp                          |   8 +-
 types/DoubleType.hpp                            |   5 +-
 types/FloatType.hpp                             |   5 +-
 types/IntType.hpp                               |   5 +-
 types/LongType.hpp                              |   5 +-
 types/NullType.hpp                              |   6 +-
 types/NumericSuperType.hpp                      |  36 +-
 types/NumericTypeSafeCoercibility.hpp           |  22 +-
 types/NumericTypeUnifier.hpp                    |  11 +-
 types/Type.hpp                                  | 146 -------
 types/TypeFactory.cpp                           |   7 +-
 types/TypeIDSelectors.hpp                       |  29 +-
 types/TypeRegistrar.hpp                         |  61 ++-
 types/TypeSynthesizer.hpp                       | 210 +++++++++++
 types/TypeUtil.hpp                              |   2 +-
 types/VarCharType.hpp                           |   6 +-
 types/YearMonthIntervalType.hpp                 |  11 +-
 .../ArithmeticBinaryFunctorOverloads.hpp        |  10 +-
 .../ArithmeticBinaryOperations.hpp              |  17 +-
 .../AsciiStringBinaryOperations.hpp             |   1 -
 .../BinaryOperationWrapper.hpp                  |   8 +-
 .../operations/binary_operations/CMakeLists.txt |  14 +-
 .../binary_operations/CMathBinaryOperations.hpp |   6 +-
 types/operations/comparisons/CMakeLists.txt     |   4 +-
 .../comparisons/PatternMatchingComparison.cpp   |   4 +-
 .../AsciiStringUnaryOperations.hpp              |   6 +-
 .../operations/unary_operations/CMakeLists.txt  |   6 +-
 .../unary_operations/CMathUnaryOperations.hpp   |  34 +-
 .../unary_operations/CastOperation.cpp          |  12 +-
 .../unary_operations/SubstringOperation.cpp     |   4 +-
 utility/CMakeLists.txt                          |  12 +-
 utility/TemplateUtil.hpp                        | 378 -------------------
 utility/meta/CMakeLists.txt                     |  41 ++
 utility/meta/Common.hpp                         | 143 +++++++
 utility/meta/Dispatchers.hpp                    | 107 ++++++
 utility/meta/TMP.hpp                            |  28 ++
 utility/meta/TransitiveClosure.hpp              |  97 +++++
 utility/meta/TypeList.hpp                       | 124 ++++++
 utility/meta/TypeListMetaFunctions.hpp          | 245 ++++++++++++
 utility/tests/TemplateUtil_unittest.cpp         | 115 ------
 47 files changed, 1230 insertions(+), 842 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/storage/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/storage/CMakeLists.txt b/storage/CMakeLists.txt
index 925be40..40eb01f 100644
--- a/storage/CMakeLists.txt
+++ b/storage/CMakeLists.txt
@@ -819,7 +819,7 @@ target_link_libraries(quickstep_storage_PackedPayloadHashTable
                       quickstep_utility_HashPair
                       quickstep_utility_Macros
                       quickstep_utility_PrimeNumber
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Dispatchers)
 target_link_libraries(quickstep_storage_PartitionedHashTablePool
                       glog
                       quickstep_storage_HashTableBase

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/storage/PackedPayloadHashTable.cpp
----------------------------------------------------------------------
diff --git a/storage/PackedPayloadHashTable.cpp b/storage/PackedPayloadHashTable.cpp
index 1df20d0..77f512b 100644
--- a/storage/PackedPayloadHashTable.cpp
+++ b/storage/PackedPayloadHashTable.cpp
@@ -40,7 +40,7 @@
 #include "utility/Alignment.hpp"
 #include "utility/Macros.hpp"
 #include "utility/PrimeNumber.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
@@ -246,7 +246,7 @@ bool PackedPayloadHashTable::upsertValueAccessorCompositeKey(
     derived_accessor->beginIterationVirtual();
   }
 
-  return InvokeOnBools(
+  return meta::InvokeOnBools(
       handles_.empty(),
       !all_keys_inline_,
       [&](auto key_only,  // NOLINT(build/c++11)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/AsciiStringSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/AsciiStringSuperType.hpp b/types/AsciiStringSuperType.hpp
index 16a8285..959c288 100644
--- a/types/AsciiStringSuperType.hpp
+++ b/types/AsciiStringSuperType.hpp
@@ -24,6 +24,7 @@
 
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 
 namespace quickstep {
 
@@ -34,10 +35,8 @@ namespace quickstep {
 /**
  * @brief A superclass for ASCII string types.
  **/
-template <typename TypeClass, TypeID type_id, TypeStorageLayout layout>
-class AsciiStringSuperType
-    : public TypeSynthesizer<TypeClass, type_id,
-                             true, layout, void, Type::kAsciiString> {
+template <TypeID type_id>
+class AsciiStringSuperType : public TypeSynthesizer<type_id> {
  public:
   bool isCoercibleFrom(const Type &original_type) const override {
     if (original_type.isNullable() && !this->nullable_) {
@@ -61,8 +60,8 @@ class AsciiStringSuperType
                        const std::size_t minimum_byte_length,
                        const std::size_t maximum_byte_length,
                        const std::size_t string_length)
-      : TypeSynthesizer<TypeClass, type_id, true, layout, void, Type::kAsciiString>(
-            Type::kAsciiString, type_id, nullable, minimum_byte_length, maximum_byte_length),
+      : TypeSynthesizer<type_id>(
+            nullable, minimum_byte_length, maximum_byte_length, string_length),
         length_(string_length) {
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/CMakeLists.txt b/types/CMakeLists.txt
index 2419e0c..6e25435 100644
--- a/types/CMakeLists.txt
+++ b/types/CMakeLists.txt
@@ -57,6 +57,7 @@ add_library(quickstep_types_TypeFactory TypeFactory.cpp TypeFactory.hpp)
 add_library(quickstep_types_TypeID TypeID.cpp TypeID.hpp)
 add_library(quickstep_types_TypeIDSelectors ../empty_src.cpp TypeIDSelectors.hpp)
 add_library(quickstep_types_TypeRegistrar ../empty_src.cpp TypeRegistrar.hpp)
+add_library(quickstep_types_TypeSynthesizer ../empty_src.cpp TypeSynthesizer.hpp)
 add_library(quickstep_types_TypeUtil ../empty_src.cpp TypeUtil.hpp)
 add_library(quickstep_types_Type_proto ${types_Type_proto_srcs})
 add_library(quickstep_types_TypedValue TypedValue.cpp TypedValue.hpp)
@@ -67,7 +68,8 @@ add_library(quickstep_types_YearMonthIntervalType YearMonthIntervalType.cpp Year
 # Link dependencies:
 target_link_libraries(quickstep_types_AsciiStringSuperType
                       quickstep_types_Type
-                      quickstep_types_TypeID)
+                      quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer)
 target_link_libraries(quickstep_types_BoolType
                       glog
                       quickstep_types_Type
@@ -95,6 +97,7 @@ target_link_libraries(quickstep_types_DateType
                       quickstep_types_DatetimeLit
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -104,6 +107,7 @@ target_link_libraries(quickstep_types_DatetimeIntervalType
                       quickstep_types_IntervalParser
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -114,6 +118,7 @@ target_link_libraries(quickstep_types_DatetimeType
                       quickstep_types_DatetimeLit
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_types_port_gmtime_r
                       quickstep_types_port_timegm
@@ -162,15 +167,20 @@ target_link_libraries(quickstep_types_NullType
                       glog
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_NumericSuperType
                       quickstep_types_NullCoercibilityCheckMacro
+                      quickstep_types_NumericTypeSafeCoercibility
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeSafeCoercibility
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_TMP)
 target_link_libraries(quickstep_types_NumericTypeUnifier
                       quickstep_types_NumericTypeSafeCoercibility)
 target_link_libraries(quickstep_types_Type
@@ -178,8 +188,7 @@ target_link_libraries(quickstep_types_Type
                       quickstep_types_Type_proto
                       quickstep_types_TypeID
                       quickstep_types_TypedValue
-                      quickstep_utility_Macros
-                      quickstep_utility_PtrMap)
+                      quickstep_utility_Macros)
 target_link_libraries(quickstep_types_TypeFactory
                       glog
                       quickstep_types_CharType
@@ -203,10 +212,21 @@ target_link_libraries(quickstep_types_TypeID
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_types_TypeIDSelectors
                       quickstep_types_TypeID
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_TypeRegistrar
+                      quickstep_types_DatetimeLit
+                      quickstep_types_IntervalLit
+                      quickstep_types_Type
+                      quickstep_types_TypeID
+                      quickstep_types_TypeIDSelectors
+                      quickstep_utility_meta_Common)
+target_link_libraries(quickstep_types_TypeSynthesizer
+                      quickstep_types_Type
                       quickstep_types_TypeID
-                      quickstep_types_TypeIDSelectors)
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_Type_proto
+                      quickstep_utility_Macros
+                      quickstep_utility_PtrMap)
 target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_CharType
                       quickstep_types_DateType
@@ -220,7 +240,6 @@ target_link_libraries(quickstep_types_TypeUtil
                       quickstep_types_Type
                       quickstep_types_TypeID
                       quickstep_types_TypeRegistrar
-                      quickstep_types_Type_proto
                       quickstep_types_VarCharType
                       quickstep_types_YearMonthIntervalType
                       quickstep_utility_Macros)
@@ -256,6 +275,7 @@ target_link_libraries(quickstep_types_YearMonthIntervalType
                       quickstep_types_IntervalParser
                       quickstep_types_Type
                       quickstep_types_TypeID
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_utility_CheckSnprintf
                       quickstep_utility_Macros)
@@ -288,6 +308,9 @@ target_link_libraries(quickstep_types
                       quickstep_types_TypeErrors
                       quickstep_types_TypeFactory
                       quickstep_types_TypeID
+                      quickstep_types_TypeIDSelectors
+                      quickstep_types_TypeRegistrar
+                      quickstep_types_TypeSynthesizer
                       quickstep_types_TypedValue
                       quickstep_types_TypedValue_proto
                       quickstep_types_VarCharType

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/CharType.hpp
----------------------------------------------------------------------
diff --git a/types/CharType.hpp b/types/CharType.hpp
index 919cc9c..c90a8da 100644
--- a/types/CharType.hpp
+++ b/types/CharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       represented WITHOUT a null-terminator character. Any strings shorter
  *       than the maximum length will have a null-terminator.
  **/
-class CharType : public AsciiStringSuperType<CharType, kChar, kNonNativeInline> {
+class CharType : public AsciiStringSuperType<kChar> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
@@ -67,9 +67,7 @@ class CharType : public AsciiStringSuperType<CharType, kChar, kNonNativeInline>
 
  private:
   CharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType<CharType, kChar, kNonNativeInline>(
-            nullable, length, length, length) {
-  }
+      : AsciiStringSuperType<kChar>(nullable, length, length, length) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/DateType.hpp
----------------------------------------------------------------------
diff --git a/types/DateType.hpp b/types/DateType.hpp
index d9356a2..088c125 100644
--- a/types/DateType.hpp
+++ b/types/DateType.hpp
@@ -27,6 +27,7 @@
 #include "types/DatetimeLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -40,7 +41,7 @@ class TypedValue;
 /**
  * @brief A type representing the date.
  **/
-class DateType : public TypeSynthesizer<DateType, kDate, false, kNativeEmbedded, DateLit> {
+class DateType : public TypeSynthesizer<kDate> {
  public:
   int getPrintWidth() const override {
     return DateLit::kIsoChars;
@@ -65,10 +66,7 @@ class DateType : public TypeSynthesizer<DateType, kDate, false, kNativeEmbedded,
 
  private:
   explicit DateType(const bool nullable)
-      : TypeSynthesizer<DateType, kDate, false, kNativeEmbedded, DateLit>(
-             Type::kOther, kStaticTypeID, nullable,
-             sizeof(DateLit), sizeof(DateLit)) {
-  }
+      : TypeSynthesizer<kDate>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/DatetimeIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeIntervalType.hpp b/types/DatetimeIntervalType.hpp
index 25eb231..d22f965 100644
--- a/types/DatetimeIntervalType.hpp
+++ b/types/DatetimeIntervalType.hpp
@@ -28,6 +28,7 @@
 #include "types/IntervalLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
 
@@ -40,9 +41,7 @@ namespace quickstep {
 /**
  * @brief A type representing the datetime interval.
  **/
-class DatetimeIntervalType :
-    public TypeSynthesizer<DatetimeIntervalType, kDatetimeInterval,
-                           false, kNativeEmbedded, DatetimeIntervalLit> {
+class DatetimeIntervalType : public TypeSynthesizer<kDatetimeInterval> {
  public:
   int getPrintWidth() const override {
     return DatetimeIntervalLit::kPrintingChars;
@@ -59,11 +58,7 @@ class DatetimeIntervalType :
 
  private:
   explicit DatetimeIntervalType(const bool nullable)
-      : TypeSynthesizer<DatetimeIntervalType, kDatetimeInterval,
-                        false, kNativeEmbedded, DatetimeIntervalLit>(
-             Type::kOther, kStaticTypeID, nullable,
-             sizeof(DatetimeIntervalLit), sizeof(DatetimeIntervalLit)) {
-  }
+      : TypeSynthesizer<kDatetimeInterval>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/DatetimeType.hpp
----------------------------------------------------------------------
diff --git a/types/DatetimeType.hpp b/types/DatetimeType.hpp
index e08e39b..6ee15c6 100644
--- a/types/DatetimeType.hpp
+++ b/types/DatetimeType.hpp
@@ -27,6 +27,7 @@
 #include "types/DatetimeLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "utility/Macros.hpp"
 
 namespace quickstep {
@@ -41,7 +42,7 @@ class TypedValue;
  * @brief A type representing the datetime.
  **/
 class DatetimeType
-    : public TypeSynthesizer<DatetimeType, kDatetime, false, kNativeEmbedded, DatetimeLit> {
+    : public TypeSynthesizer<kDatetime> {
  public:
   int getPrintWidth() const override {
     return DatetimeLit::kIsoChars;
@@ -74,10 +75,7 @@ class DatetimeType
 
  private:
   explicit DatetimeType(const bool nullable)
-      : TypeSynthesizer<DatetimeType, kDatetime, false, kNativeEmbedded, DatetimeLit>(
-             Type::kOther, kStaticTypeID, nullable,
-             sizeof(DatetimeLit), sizeof(DatetimeLit)) {
-  }
+      : TypeSynthesizer<kDatetime>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/DoubleType.hpp
----------------------------------------------------------------------
diff --git a/types/DoubleType.hpp b/types/DoubleType.hpp
index a431e0a..a41c68f 100644
--- a/types/DoubleType.hpp
+++ b/types/DoubleType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a double-precision floating-point number.
  **/
-class DoubleType : public NumericSuperType<DoubleType, kDouble, double> {
+class DoubleType : public NumericSuperType<kDouble> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
@@ -77,8 +77,7 @@ class DoubleType : public NumericSuperType<DoubleType, kDouble, double> {
               // exponent never takes more than 3 base-10 digits to represent.
 
   explicit DoubleType(const bool nullable)
-      : NumericSuperType<DoubleType, kDouble, double>(nullable) {
-  }
+      : NumericSuperType<kDouble>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/FloatType.hpp
----------------------------------------------------------------------
diff --git a/types/FloatType.hpp b/types/FloatType.hpp
index 29c05f0..7c489d3 100644
--- a/types/FloatType.hpp
+++ b/types/FloatType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a single-precision floating-point number.
  **/
-class FloatType : public NumericSuperType<FloatType, kFloat, float> {
+class FloatType : public NumericSuperType<kFloat> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
@@ -77,8 +77,7 @@ class FloatType : public NumericSuperType<FloatType, kFloat, float> {
               // never takes more than 2 base-10 digits to represent.
 
   explicit FloatType(const bool nullable)
-      : NumericSuperType<FloatType, kFloat, float>(nullable) {
-  }
+      : NumericSuperType<kFloat>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/IntType.hpp
----------------------------------------------------------------------
diff --git a/types/IntType.hpp b/types/IntType.hpp
index 0ef3da9..8d4451d 100644
--- a/types/IntType.hpp
+++ b/types/IntType.hpp
@@ -40,7 +40,7 @@ class Type;
 /**
  * @brief A type representing a 32-bit integer.
  **/
-class IntType : public NumericSuperType<IntType, kInt, int> {
+class IntType : public NumericSuperType<kInt> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
@@ -64,8 +64,7 @@ class IntType : public NumericSuperType<IntType, kInt, int> {
 
  private:
   explicit IntType(const bool nullable)
-      : NumericSuperType<IntType, kInt, int>(nullable) {
-  }
+      : NumericSuperType<kInt>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/LongType.hpp
----------------------------------------------------------------------
diff --git a/types/LongType.hpp b/types/LongType.hpp
index 76569c1..f963a4f 100644
--- a/types/LongType.hpp
+++ b/types/LongType.hpp
@@ -41,7 +41,7 @@ class Type;
 /**
  * @brief A type representing a 64-bit integer.
  **/
-class LongType : public NumericSuperType<LongType, kLong, std::int64_t> {
+class LongType : public NumericSuperType<kLong> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override;
 
@@ -65,8 +65,7 @@ class LongType : public NumericSuperType<LongType, kLong, std::int64_t> {
 
  private:
   explicit LongType(const bool nullable)
-      : NumericSuperType<LongType, kLong, std::int64_t>(nullable) {
-  }
+      : NumericSuperType<kLong>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/NullType.hpp
----------------------------------------------------------------------
diff --git a/types/NullType.hpp b/types/NullType.hpp
index 647c2f7..c416a05 100644
--- a/types/NullType.hpp
+++ b/types/NullType.hpp
@@ -26,6 +26,7 @@
 
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "utility/Macros.hpp"
 
 #include "glog/logging.h"
@@ -48,7 +49,7 @@ class TypedValue;
  *       a particular operation may accept. It is also assumed that applying
  *       any operation to an argument of NullType always yields NULL values.
  **/
-class NullType : public TypeSynthesizer<NullType, kNullType, false, kNativeEmbedded> {
+class NullType : public TypeSynthesizer<kNullType> {
  public:
   static const NullType& InstanceNonNullable() {
     LOG(FATAL) << "Called NullType::InstanceNonNullable(), "
@@ -87,8 +88,7 @@ class NullType : public TypeSynthesizer<NullType, kNullType, false, kNativeEmbed
   // NOTE(chasseur): NullType requires 0 bytes of inherent storage. It does,
   // however, require a bit in NULL bitmaps.
   NullType(const bool nullable)
-      : TypeSynthesizer<NullType, kNullType, false, kNativeEmbedded>(
-            Type::kOther, kStaticTypeID, true, 0, 0) {
+      : TypeSynthesizer<kNullType>(nullable, 0, 0) {
     DCHECK(nullable);
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/NumericSuperType.hpp
----------------------------------------------------------------------
diff --git a/types/NumericSuperType.hpp b/types/NumericSuperType.hpp
index 066ca1e..94a8d03 100644
--- a/types/NumericSuperType.hpp
+++ b/types/NumericSuperType.hpp
@@ -27,8 +27,11 @@
 #include "types/NumericTypeSafeCoercibility.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
+#include "utility/meta/TMP.hpp"
 
 namespace quickstep {
 
@@ -40,10 +43,8 @@ namespace quickstep {
  * @brief Templatized superclass for Numeric types. Contains code common to all
  *        Numeric types.
  **/
-template <typename TypeClass, TypeID type_id, typename CppType>
-class NumericSuperType
-    : public TypeSynthesizer<TypeClass, type_id,
-                             false, kNativeEmbedded, CppType, Type::kNumeric> {
+template <TypeID type_id>
+class NumericSuperType : public TypeSynthesizer<type_id> {
  public:
   bool isSafelyCoercibleFrom(const Type &original_type) const override {
     const auto it = safe_coerce_cache_.find(original_type.getTypeID());
@@ -56,17 +57,34 @@ class NumericSuperType
   }
 
   TypedValue makeZeroValue() const override {
-    return TypedValue(static_cast<CppType>(0));
+    return TypedValue(static_cast<typename TypeIDTrait<type_id>::cpptype>(0));
   }
 
  protected:
   explicit NumericSuperType(const bool nullable)
-      : TypeSynthesizer<TypeClass, type_id,
-                        false, kNativeEmbedded, CppType, Type::kNumeric>(
-            Type::kNumeric, type_id, nullable, sizeof(CppType), sizeof(CppType)) {}
+      : TypeSynthesizer<type_id>(nullable),
+        safe_coerce_cache_(CreateSafeCoercibilityCache()) {}
 
  private:
-  std::unordered_set<TypeID> safe_coerce_cache_;
+  using TargetType = typename TypeIDTrait<type_id>::TypeClass;
+
+  template <typename SourceTypeID>
+  struct SafeCoercibilityFilter {
+    static constexpr bool value =
+        NumericTypeSafeCoercibility<
+            typename TypeIDTrait<SourceTypeID::value>::TypeClass,
+            TargetType>::value;
+  };
+
+  inline static auto CreateSafeCoercibilityCache() {
+    using SourceTypeIDs = TypeIDSequenceAll::template bind_to<meta::TypeList>;
+    using ResultTypeIDs = SourceTypeIDs::template filter<SafeCoercibilityFilter>;
+
+    return ResultTypeIDs::template as_sequence<TypeID>
+        ::template Instantiate<std::unordered_set<TypeID>>();
+  };
+
+  const std::unordered_set<TypeID> safe_coerce_cache_;
 
   DISALLOW_COPY_AND_ASSIGN(NumericSuperType);
 };

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/NumericTypeSafeCoercibility.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeSafeCoercibility.hpp b/types/NumericTypeSafeCoercibility.hpp
index 2ef29b7..914927c 100644
--- a/types/NumericTypeSafeCoercibility.hpp
+++ b/types/NumericTypeSafeCoercibility.hpp
@@ -20,7 +20,7 @@
 #ifndef QUICKSTEP_TYPES_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
 #define QUICKSTEP_TYPES_NUMERIC_TYPE_SAFE_COERCIBILITY_HPP_
 
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/TMP.hpp"
 
 namespace quickstep {
 
@@ -34,22 +34,24 @@ class LongType;
  *  @{
  */
 
-using NumericTypeSafeCoersions = TypeList<
-    TypeList<BoolType, IntType>,
-    TypeList<IntType, FloatType>,
-    TypeList<IntType, LongType>,
-    TypeList<FloatType, DoubleType>,
-    TypeList<LongType, DoubleType>
->;
+template <typename LeftType, typename RightType>
+using IsSafelyCoercible = meta::TypeList<LeftType, RightType>;
 
-using NumericTypeSafeCoersionClosure = TransitiveClosure<NumericTypeSafeCoersions>;
+using NumericTypeSafeCoersionPartialOrder = meta::TypeList<
+    IsSafelyCoercible<BoolType, IntType>,
+    IsSafelyCoercible<IntType, FloatType>,
+    IsSafelyCoercible<IntType, LongType>,
+    IsSafelyCoercible<FloatType, DoubleType>,
+    IsSafelyCoercible<LongType, DoubleType>>;
 
+using NumericTypeSafeCoersionClosure =
+    meta::TransitiveClosure<NumericTypeSafeCoersionPartialOrder>;
 
 template <typename LeftType, typename RightType>
 struct NumericTypeSafeCoercibility {
   static constexpr bool value =
       NumericTypeSafeCoersionClosure::contains<
-          TypeList<LeftType, RightType>>::value;
+          IsSafelyCoercible<LeftType, RightType>>::value;
 };
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/NumericTypeUnifier.hpp
----------------------------------------------------------------------
diff --git a/types/NumericTypeUnifier.hpp b/types/NumericTypeUnifier.hpp
index 6253a18..0c3f13f 100644
--- a/types/NumericTypeUnifier.hpp
+++ b/types/NumericTypeUnifier.hpp
@@ -49,16 +49,13 @@ struct NumericTypeUnifier;
 
 namespace internal {
 
-using NumericTypeSafeCoersionClosure = TransitiveClosure<NumericTypeSafeCoersions>;
-
 template <typename LeftType, typename RightType, typename EnableT = void>
 struct NumericTypeUnifierHelper;
 
 template <typename LeftType, typename RightType>
 struct NumericTypeUnifierHelper<
     LeftType, RightType,
-    std::enable_if_t<NumericTypeSafeCoersionClosure::contains<
-                         TypeList<LeftType, RightType>>::value>> {
+    std::enable_if_t<NumericTypeSafeCoercibility<LeftType, RightType>::value>> {
   typedef RightType type;
 };
 
@@ -66,13 +63,11 @@ template <typename LeftType, typename RightType>
 struct NumericTypeUnifierHelper<
     LeftType, RightType,
     std::enable_if_t<!std::is_same<LeftType, RightType>::value &&
-                     NumericTypeSafeCoersionClosure::contains<
-                         TypeList<RightType, LeftType>>::value>> {
+                     NumericTypeSafeCoercibility<RightType, LeftType>::value>> {
   typedef LeftType type;
 };
 
-// Explicit template specializations for all combinations of builtin numeric
-// types.
+// Explicit template specializations
 template<>
 struct NumericTypeUnifierHelper<LongType, FloatType> {
   typedef DoubleType type;

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/Type.hpp
----------------------------------------------------------------------
diff --git a/types/Type.hpp b/types/Type.hpp
index 4f2042a..bf6c167 100644
--- a/types/Type.hpp
+++ b/types/Type.hpp
@@ -24,13 +24,11 @@
 #include <cstdint>
 #include <cstdio>
 #include <string>
-#include <type_traits>
 
 #include "types/Type.pb.h"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
-#include "utility/PtrMap.hpp"
 
 #include "glog/logging.h"
 
@@ -467,150 +465,6 @@ class Type {
   DISALLOW_COPY_AND_ASSIGN(Type);
 };
 
-
-template <typename TypeClass, bool parameterized>
-class TypeInstance;
-
-template <typename TypeClass>
-class TypeInstance<TypeClass, false> {
- public:
-  static const TypeClass& InstanceNonNullable() {
-    return InstanceInternal<false>();
-  }
-
-  static const TypeClass& InstanceNullable() {
-    return InstanceInternal<true>();
-  }
-
-  static const TypeClass& Instance(const bool nullable) {
-    if (nullable) {
-      return InstanceNullable();
-    } else {
-      return InstanceNonNullable();
-    }
-  }
-
- private:
-  template <bool nullable>
-  inline static const TypeClass& InstanceInternal() {
-    static TypeClass instance(nullable);
-    return instance;
-  }
-};
-
-template <typename TypeClass>
-class TypeInstance<TypeClass, true> {
- public:
-  static const TypeClass& InstanceNonNullable(const std::size_t length) {
-    return InstanceInternal<false>(length);
-  }
-
-  static const TypeClass& InstanceNullable(const std::size_t length) {
-    return InstanceInternal<true>(length);
-  }
-
-  static const TypeClass& Instance(const std::size_t length, const bool nullable) {
-    if (nullable) {
-      return InstanceNullable(length);
-    } else {
-      return InstanceNonNullable(length);
-    }
-  }
-
- private:
-  template <bool nullable>
-  inline static const TypeClass& InstanceInternal(const std::size_t length) {
-    static PtrMap<size_t, TypeClass> instance_map;
-    auto imit = instance_map.find(length);
-    if (imit == instance_map.end()) {
-      imit = instance_map.insert(length, new TypeClass(length, nullable)).first;
-    }
-    return *(imit->second);
-  }
-};
-
-
-template <typename TypeClass, TypeID type_id,
-          bool parameterized, TypeStorageLayout layout,
-          typename CppType = void,
-          Type::SuperTypeID super_type_id = Type::kOther>
-class TypeSynthesizer : public Type, public TypeInstance<TypeClass, parameterized> {
- public:
-  static constexpr Type::SuperTypeID kStaticSuperTypeID = super_type_id;
-  static constexpr TypeID kStaticTypeID = type_id;
-  static constexpr bool kParameterized = parameterized;
-  static constexpr TypeStorageLayout kLayout = layout;
-
-  typedef CppType cpptype;
-
-  serialization::Type getProto() const override {
-    serialization::Type proto;
-
-    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
-    proto.set_nullable(nullable_);
-
-    if (kParameterized) {
-      proto.set_length(parameter_);
-    }
-
-    return proto;
-  }
-
-  const Type& getNullableVersion() const override {
-    return getInstance<kParameterized>(true);
-  }
-
-  const Type& getNonNullableVersion() const override {
-    return getInstance<kParameterized>(false);
-  }
-
- protected:
-  template <typename ...ArgTypes>
-  explicit TypeSynthesizer(ArgTypes &&...args)
-      : Type(std::forward<ArgTypes>(args)...) {}
-
- private:
-  template <bool has_param>
-  inline const Type& getInstance(const bool nullable,
-                                 std::enable_if_t<has_param>* = 0) const {
-    return TypeInstance<TypeClass, kParameterized>::Instance(parameter_, nullable);
-  }
-
-  template <bool has_param>
-  inline const Type& getInstance(const bool nullable,
-                                 std::enable_if_t<!has_param>* = 0) const {
-    return TypeInstance<TypeClass, kParameterized>::Instance(nullable);
-  }
-
-  friend class TypeInstance<TypeClass, kParameterized>;
-
-  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
-};
-
-template <typename TypeClass, TypeID type_id,
-          bool parameterized, TypeStorageLayout layout,
-          typename CppType, Type::SuperTypeID super_type_id>
-constexpr Type::SuperTypeID TypeSynthesizer<
-    TypeClass, type_id, parameterized, layout, CppType, super_type_id>::kStaticSuperTypeID;
-
-template <typename TypeClass, TypeID type_id,
-          bool parameterized, TypeStorageLayout layout,
-          typename CppType, Type::SuperTypeID super_type_id>
-constexpr TypeID TypeSynthesizer<
-    TypeClass, type_id, parameterized, layout, CppType, super_type_id>::kStaticTypeID;
-
-template <typename TypeClass, TypeID type_id,
-          bool parameterized, TypeStorageLayout layout,
-          typename CppType, Type::SuperTypeID super_type_id>
-constexpr bool TypeSynthesizer<
-    TypeClass, type_id, parameterized, layout, CppType, super_type_id>::kParameterized;
-
-template <typename TypeClass, TypeID type_id,
-          bool parameterized, TypeStorageLayout layout,
-          typename CppType, Type::SuperTypeID super_type_id>
-constexpr TypeStorageLayout TypeSynthesizer<
-    TypeClass, type_id, parameterized, layout, CppType, super_type_id>::kLayout;
-
 /** @} */
 
 }  // namespace quickstep

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/TypeFactory.cpp
----------------------------------------------------------------------
diff --git a/types/TypeFactory.cpp b/types/TypeFactory.cpp
index 4a24cc6..078f495 100644
--- a/types/TypeFactory.cpp
+++ b/types/TypeFactory.cpp
@@ -56,7 +56,7 @@ const Type& TypeFactory::GetType(const TypeID id,
   return *InvokeOnTypeID<TypeIDSelectorNonParameterized>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
-    return &TypeClass<decltype(id)::value>::type::Instance(nullable);
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable);
   });
 }
 
@@ -70,7 +70,7 @@ const Type& TypeFactory::GetType(const TypeID id,
   return *InvokeOnTypeID<TypeIDSelectorParameterized>(
       id,
       [&](auto id) -> const Type* {  // NOLINT(build/c++11)
-    return &TypeClass<decltype(id)::value>::type::Instance(nullable, length);
+    return &TypeIDTrait<decltype(id)::value>::TypeClass::Instance(nullable, length);
   });
 }
 
@@ -121,7 +121,8 @@ const Type* TypeFactory::GetMostSpecificType(const Type &first, const Type &seco
 const Type* TypeFactory::GetUnifyingType(const Type &first, const Type &second) {
   const Type *unifier = nullptr;
   if (first.isNullable() || second.isNullable()) {
-    unifier = GetMostSpecificType(first.getNullableVersion(), second.getNullableVersion());
+    unifier = GetMostSpecificType(first.getNullableVersion(),
+                                  second.getNullableVersion());
     if (unifier == nullptr) {
       if (((first.getTypeID() == kLong) && (second.getTypeID() == kFloat))
             || ((first.getTypeID() == kFloat) && (second.getTypeID() == kLong))) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/TypeIDSelectors.hpp
----------------------------------------------------------------------
diff --git a/types/TypeIDSelectors.hpp b/types/TypeIDSelectors.hpp
index 8e0ac9f..d75a887 100644
--- a/types/TypeIDSelectors.hpp
+++ b/types/TypeIDSelectors.hpp
@@ -23,6 +23,7 @@
 #include <type_traits>
 
 #include "types/TypeID.hpp"
+#include "utility/meta/Common.hpp"
 
 #include "glog/logging.h"
 
@@ -46,7 +47,16 @@ struct TypeIDSelectorEqualsAny;
 
 // Forward declaration
 template <TypeID type_id>
-struct TypeClass;
+struct TypeIDTrait;
+
+struct TypeIDSelectorAll {
+  template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
+  struct Implementation {
+    inline static auto Invoke(const FunctorT &functor) {
+      return functor(TypeIDConstant());
+    }
+  };
+};
 
 struct TypeIDSelectorNumeric {
   template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
@@ -65,7 +75,7 @@ struct TypeIDSelectorNumeric {
 template <typename TypeIDConstant, typename FunctorT>
 struct TypeIDSelectorNumeric::Implementation<
     TypeIDConstant, FunctorT,
-    std::enable_if_t<TypeClass<TypeIDConstant::value>::type
+    std::enable_if_t<TypeIDTrait<TypeIDConstant::value>
                          ::kStaticSuperTypeID == Type::kNumeric>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
@@ -92,8 +102,8 @@ template <typename TypeIDConstant, typename FunctorT>
 struct TypeIDSelectorEqualsAny<candidates...>::Implementation<
     TypeIDConstant, FunctorT,
     std::enable_if_t<
-        EqualsAny<TypeIDConstant,
-                  std::integral_constant<TypeID, candidates>...>::value>> {
+        meta::EqualsAny<TypeIDConstant,
+                        std::integral_constant<TypeID, candidates>...>::value>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
   }
@@ -120,7 +130,7 @@ template <bool require_non_parameterized>
 template <typename TypeIDConstant, typename FunctorT>
 struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementation<
     TypeIDConstant, FunctorT,
-    std::enable_if_t<TypeClass<TypeIDConstant::value>::type::kParameterized
+    std::enable_if_t<TypeIDTrait<TypeIDConstant::value>::kParameterized
                          ^ require_non_parameterized>> {
   inline static auto Invoke(const FunctorT &functor) {
     return functor(TypeIDConstant());
@@ -129,15 +139,6 @@ struct TypeIDSelectorParameterizedHelper<require_non_parameterized>::Implementat
 
 }  // namespace internal
 
-struct TypeIDSelectorAll {
-  template <typename TypeIDConstant, typename FunctorT, typename EnableT = void>
-  struct Implementation {
-    inline static auto Invoke(const FunctorT &functor) {
-      return functor(TypeIDConstant());
-    }
-  };
-};
-
 struct TypeIDSelectorNonParameterized
     : internal::TypeIDSelectorParameterizedHelper<true> {};
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/TypeRegistrar.hpp
----------------------------------------------------------------------
diff --git a/types/TypeRegistrar.hpp b/types/TypeRegistrar.hpp
index 3366cd9..6a02b35 100644
--- a/types/TypeRegistrar.hpp
+++ b/types/TypeRegistrar.hpp
@@ -20,10 +20,15 @@
 #ifndef QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
 #define QUICKSTEP_TYPES_TYPE_REGISTRAR_HPP_
 
+#include <cstdint>
 #include <type_traits>
 
+#include "types/DatetimeLit.hpp"
+#include "types/IntervalLit.hpp"
+#include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypeIDSelectors.hpp"
+#include "utility/meta/Common.hpp"
 
 #include "glog/logging.h"
 
@@ -34,31 +39,51 @@ namespace quickstep {
  */
 
 template <TypeID type_id>
-struct TypeClass;
-
-#define REGISTER_TYPE(T, TID) \
-  class T;\
-  template <> struct TypeClass<TID> { typedef T type; };
-
-REGISTER_TYPE(IntType, kInt);
-REGISTER_TYPE(LongType, kLong);
-REGISTER_TYPE(FloatType, kFloat);
-REGISTER_TYPE(DoubleType, kDouble);
-REGISTER_TYPE(DateType, kDate);
-REGISTER_TYPE(DatetimeType, kDatetime);
-REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval);
-REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval);
-REGISTER_TYPE(CharType, kChar);
-REGISTER_TYPE(VarCharType, kVarChar);
-REGISTER_TYPE(NullType, kNullType);
+struct TypeIDTrait;
+
+#define REGISTER_TYPE(T, type_id, super_type_id, parameterized, layout, CppType) \
+  class T; \
+  template <> struct TypeIDTrait<type_id> { \
+    typedef T TypeClass; \
+    typedef CppType cpptype; \
+    static constexpr TypeID kStaticTypeID = type_id; \
+    static constexpr Type::SuperTypeID kStaticSuperTypeID = super_type_id; \
+    static constexpr bool kParameterized = parameterized; \
+    static constexpr TypeStorageLayout kLayout = layout; \
+  };
+
+REGISTER_TYPE(IntType, kInt, \
+              Type::kNumeric, false, kNativeEmbedded, int);
+REGISTER_TYPE(LongType, kLong, \
+              Type::kNumeric, false, kNativeEmbedded, std::int64_t);
+REGISTER_TYPE(FloatType, kFloat, \
+              Type::kNumeric, false, kNativeEmbedded, float);
+REGISTER_TYPE(DoubleType, kDouble, \
+              Type::kNumeric, false, kNativeEmbedded, double);
+REGISTER_TYPE(DateType, kDate, \
+              Type::kOther, false, kNativeEmbedded, DateLit);
+REGISTER_TYPE(DatetimeType, kDatetime, \
+              Type::kOther, false, kNativeEmbedded, DatetimeLit);
+REGISTER_TYPE(DatetimeIntervalType, kDatetimeInterval, \
+              Type::kOther, false, kNativeEmbedded, DatetimeIntervalLit);
+REGISTER_TYPE(YearMonthIntervalType, kYearMonthInterval, \
+              Type::kOther, false, kNativeEmbedded, YearMonthIntervalLit);
+REGISTER_TYPE(CharType, kChar, \
+              Type::kAsciiString, true, kNonNativeInline, void);
+REGISTER_TYPE(VarCharType, kVarChar, \
+              Type::kAsciiString, true, kOutOfLine, void);
+REGISTER_TYPE(NullType, kNullType, \
+              Type::kOther, false, kNonNativeInline, void);
 
 #undef REGISTER_TYPE
 
+using TypeIDSequenceAll =
+    meta::MakeSequence<static_cast<std::size_t>(kNumTypeIDs)>
+        ::type::template cast_to<TypeID>;
 
 template <typename Selector = TypeIDSelectorAll, typename FunctorT>
 auto InvokeOnTypeID(const TypeID type_id, const FunctorT &functor);
 
-
 namespace internal {
 
 template <int l, int r, typename Selector, typename FunctorT>

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/TypeSynthesizer.hpp
----------------------------------------------------------------------
diff --git a/types/TypeSynthesizer.hpp b/types/TypeSynthesizer.hpp
new file mode 100644
index 0000000..2f6b8af
--- /dev/null
+++ b/types/TypeSynthesizer.hpp
@@ -0,0 +1,210 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ **/
+
+#ifndef QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
+#define QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_
+
+#include <cstddef>
+#include <type_traits>
+
+#include "types/Type.hpp"
+#include "types/Type.pb.h"
+#include "types/TypeID.hpp"
+#include "types/TypeRegistrar.hpp"
+#include "utility/Macros.hpp"
+#include "utility/PtrMap.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+/** \addtogroup Types
+ *  @{
+ */
+
+template <typename TypeClass, bool parameterized>
+class TypeInstance;
+
+
+template <TypeID type_id>
+class TypeSynthesizer
+    : public Type,
+      public TypeInstance<typename TypeIDTrait<type_id>::TypeClass,
+                          TypeIDTrait<type_id>::kParameterized> {
+ public:
+  using Trait = TypeIDTrait<type_id>;
+  using TypeClass = typename Trait::TypeClass;
+
+  static constexpr Type::SuperTypeID kStaticSuperTypeID = Trait::kStaticSuperTypeID;
+  static constexpr TypeID kStaticTypeID = Trait::kStaticTypeID;
+  static constexpr bool kParameterized = Trait::kParameterized;
+  static constexpr TypeStorageLayout kLayout = Trait::kLayout;
+
+  typedef typename Trait::cpptype cpptype;
+
+  serialization::Type getProto() const override {
+    serialization::Type proto;
+
+    proto.mutable_type_id()->CopyFrom(TypeIDFactory::GetProto(type_id_));
+    proto.set_nullable(nullable_);
+
+    if (kParameterized) {
+      proto.set_length(parameter_);
+    }
+
+    return proto;
+  }
+
+  const Type& getNullableVersion() const override {
+    return getInstance<kParameterized>(true);
+  }
+
+  const Type& getNonNullableVersion() const override {
+    return getInstance<kParameterized>(false);
+  }
+
+ protected:
+  template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+  explicit TypeSynthesizer(const bool nullable,
+                           std::enable_if_t<layout == kNativeEmbedded ||
+                                            layout == kNativeInline>* = 0)
+      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+             sizeof(cpptype), sizeof(cpptype)) {
+    DCHECK(!kParameterized);
+  }
+
+  template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  const std::size_t parameter,
+                  std::enable_if_t<parameterized &&
+                                   (layout == kNonNativeInline ||
+                                    layout == kOutOfLine)>* = 0)
+      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+             minimum_byte_length, maximum_byte_length, parameter) {
+    DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+  }
+
+  template <TypeStorageLayout layout = kLayout, bool parameterized = kParameterized>
+  TypeSynthesizer(const bool nullable,
+                  const std::size_t minimum_byte_length,
+                  const std::size_t maximum_byte_length,
+                  std::enable_if_t<!parameterized &&
+                                   (layout == kNonNativeInline ||
+                                    layout == kOutOfLine)>* = 0)
+      : Type(kStaticSuperTypeID, kStaticTypeID, nullable,
+             minimum_byte_length, maximum_byte_length) {
+    DCHECK(kLayout != kNonNativeInline || minimum_byte_length == maximum_byte_length);
+  }
+
+ private:
+  template <bool has_param>
+  inline const Type& getInstance(const bool nullable,
+                                 std::enable_if_t<has_param>* = 0) const {
+    return TypeInstance<TypeClass, kParameterized>::Instance(parameter_, nullable);
+  }
+
+  template <bool has_param>
+  inline const Type& getInstance(const bool nullable,
+                                 std::enable_if_t<!has_param>* = 0) const {
+    return TypeInstance<TypeClass, kParameterized>::Instance(nullable);
+  }
+
+  friend class TypeInstance<TypeClass, kParameterized>;
+
+  DISALLOW_COPY_AND_ASSIGN(TypeSynthesizer);
+};
+
+template <TypeID type_id>
+constexpr Type::SuperTypeID TypeSynthesizer<type_id>::kStaticSuperTypeID;
+
+template <TypeID type_id>
+constexpr TypeID TypeSynthesizer<type_id>::kStaticTypeID;
+
+template <TypeID type_id>
+constexpr bool TypeSynthesizer<type_id>::kParameterized;
+
+template <TypeID type_id>
+constexpr TypeStorageLayout TypeSynthesizer<type_id>::kLayout;
+
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, false> {
+ public:
+  static const TypeClass& InstanceNonNullable() {
+    return InstanceInternal<false>();
+  }
+
+  static const TypeClass& InstanceNullable() {
+    return InstanceInternal<true>();
+  }
+
+  static const TypeClass& Instance(const bool nullable) {
+    if (nullable) {
+      return InstanceNullable();
+    } else {
+      return InstanceNonNullable();
+    }
+  }
+
+ private:
+  template <bool nullable>
+  inline static const TypeClass& InstanceInternal() {
+    static TypeClass instance(nullable);
+    return instance;
+  }
+};
+
+template <typename TypeClass>
+class TypeInstance<TypeClass, true> {
+ public:
+  static const TypeClass& InstanceNonNullable(const std::size_t length) {
+    return InstanceInternal<false>(length);
+  }
+
+  static const TypeClass& InstanceNullable(const std::size_t length) {
+    return InstanceInternal<true>(length);
+  }
+
+  static const TypeClass& Instance(const std::size_t length, const bool nullable) {
+    if (nullable) {
+      return InstanceNullable(length);
+    } else {
+      return InstanceNonNullable(length);
+    }
+  }
+
+ private:
+  template <bool nullable>
+  inline static const TypeClass& InstanceInternal(const std::size_t length) {
+    static PtrMap<size_t, TypeClass> instance_map;
+    auto imit = instance_map.find(length);
+    if (imit == instance_map.end()) {
+      imit = instance_map.insert(length, new TypeClass(length, nullable)).first;
+    }
+    return *(imit->second);
+  }
+};
+
+/** @} */
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_TYPES_TYPE_SYNTHESIZER_HPP_

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/TypeUtil.hpp
----------------------------------------------------------------------
diff --git a/types/TypeUtil.hpp b/types/TypeUtil.hpp
index c1cd3fa..c614f23 100644
--- a/types/TypeUtil.hpp
+++ b/types/TypeUtil.hpp
@@ -52,7 +52,7 @@ class TypeUtil {
     return InvokeOnTypeID(
         type_id,
         [&](auto tid) -> bool {  // NOLINT(build/c++11)
-      return TypeClass<decltype(tid)::value>::type::kParameterized;
+      return TypeIDTrait<decltype(tid)::value>::kParameterized;
     });
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/VarCharType.hpp
----------------------------------------------------------------------
diff --git a/types/VarCharType.hpp b/types/VarCharType.hpp
index a8f1a8d..05b2aae 100644
--- a/types/VarCharType.hpp
+++ b/types/VarCharType.hpp
@@ -43,7 +43,7 @@ namespace quickstep {
  *       character. This means that the VARCHAR(X) type requires from 1 to X+1
  *       bytes of storage, depending on string length.
  **/
-class VarCharType : public AsciiStringSuperType<VarCharType, kVarChar, kOutOfLine> {
+class VarCharType : public AsciiStringSuperType<kVarChar> {
  public:
   /**
    * @note Includes an extra byte for a terminating null character.
@@ -74,9 +74,7 @@ class VarCharType : public AsciiStringSuperType<VarCharType, kVarChar, kOutOfLin
 
  private:
   VarCharType(const std::size_t length, const bool nullable)
-      : AsciiStringSuperType<VarCharType, kVarChar, kOutOfLine>(
-            nullable, 1, length + 1, length) {
-  }
+      : AsciiStringSuperType<kVarChar>(nullable, 1, length + 1, length) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/YearMonthIntervalType.hpp
----------------------------------------------------------------------
diff --git a/types/YearMonthIntervalType.hpp b/types/YearMonthIntervalType.hpp
index 3a22541..e890ea9 100644
--- a/types/YearMonthIntervalType.hpp
+++ b/types/YearMonthIntervalType.hpp
@@ -27,6 +27,7 @@
 #include "types/IntervalLit.hpp"
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
+#include "types/TypeSynthesizer.hpp"
 #include "types/TypedValue.hpp"
 #include "utility/Macros.hpp"
 
@@ -39,9 +40,7 @@ namespace quickstep {
 /**
  * @brief A type representing the year-month interval.
  **/
-class YearMonthIntervalType :
-    public TypeSynthesizer<YearMonthIntervalType, kYearMonthInterval,
-                           false, kNativeEmbedded, YearMonthIntervalLit> {
+class YearMonthIntervalType : public TypeSynthesizer<kYearMonthInterval> {
  public:
   int getPrintWidth() const override {
     return YearMonthIntervalLit::kPrintingChars;
@@ -58,11 +57,7 @@ class YearMonthIntervalType :
 
  private:
   explicit YearMonthIntervalType(const bool nullable)
-      : TypeSynthesizer<YearMonthIntervalType, kYearMonthInterval,
-                        false, kNativeEmbedded, YearMonthIntervalLit>(
-            Type::kOther, kStaticTypeID, nullable,
-            sizeof(YearMonthIntervalLit), sizeof(YearMonthIntervalLit)) {
-  }
+      : TypeSynthesizer<kYearMonthInterval>(nullable) {}
 
   template <typename, bool> friend class TypeInstance;
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp b/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
index b5acc8e..4c6f76c 100644
--- a/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
+++ b/types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp
@@ -27,7 +27,7 @@
 #include <utility>
 
 #include "types/DateOperatorOverloads.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -145,8 +145,8 @@ struct ModuloFunctorOverloads;
 template <typename LeftCppType, typename RightCppType>
 struct ModuloFunctorOverloads<
     LeftCppType, RightCppType,
-    std::enable_if_t<EqualsAny<LeftCppType, int, std::int64_t>::value &&
-                     EqualsAny<RightCppType, int, std::int64_t>::value>> {
+    std::enable_if_t<meta::EqualsAny<LeftCppType, int, std::int64_t>::value &&
+                     meta::EqualsAny<RightCppType, int, std::int64_t>::value>> {
   inline auto operator() (const LeftCppType &left,
                           const RightCppType &right) const -> decltype(left % right) {
     return left % right;
@@ -161,8 +161,8 @@ struct ModuloFunctorOverloads<
 template <typename LeftCppType, typename RightCppType>
 struct ModuloFunctorOverloads<
     LeftCppType, RightCppType,
-    std::enable_if_t<EqualsAny<LeftCppType, float, double>::value ||
-                     EqualsAny<RightCppType, float, double>::value>> {
+    std::enable_if_t<meta::EqualsAny<LeftCppType, float, double>::value ||
+                     meta::EqualsAny<RightCppType, float, double>::value>> {
   inline auto operator() (const LeftCppType &left,
                           const RightCppType &right) const -> decltype(std::fmod(left, right)) {
     return std::fmod(left, right);

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp b/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
index 9098f80..fa4d926 100644
--- a/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
+++ b/types/operations/binary_operations/ArithmeticBinaryOperations.hpp
@@ -37,6 +37,7 @@
 #include "types/YearMonthIntervalType.hpp"
 #include "types/operations/binary_operations/ArithmeticBinaryFunctorOverloads.hpp"
 #include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -65,27 +66,27 @@ struct ArithmeticBinaryFunctor : public BinaryFunctor<LeftT, RightT, ResultT> {
 template <typename LeftT, typename RightT, typename ResultT>
 using AddFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
                                            AddFunctorOverloads,
-                                           StringLiteral<'+'>>;
+                                           meta::StringLiteral<'+'>>;
 
 template <typename LeftT, typename RightT, typename ResultT>
 using SubtractFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
                                                 SubtractFunctorOverloads,
-                                                StringLiteral<'-'>>;
+                                                meta::StringLiteral<'-'>>;
 
 template <typename LeftT, typename RightT, typename ResultT>
 using MultiplyFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
                                                 MultiplyFunctorOverloads,
-                                                StringLiteral<'*'>>;
+                                                meta::StringLiteral<'*'>>;
 
 template <typename LeftT, typename RightT, typename ResultT>
 using DivideFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
                                               DivideFunctorOverloads,
-                                              StringLiteral<'/'>>;
+                                              meta::StringLiteral<'/'>>;
 
 template <typename LeftT, typename RightT, typename ResultT>
 using ModuloFunctor = ArithmeticBinaryFunctor<LeftT, RightT, ResultT,
                                               ModuloFunctorOverloads,
-                                              StringLiteral<'%'>>;
+                                              meta::StringLiteral<'%'>>;
 
 // ----------------------------------------------------------------------------
 // Packs of functors:
@@ -140,11 +141,11 @@ using MultiplyBinaryFunctorPack = FunctorPack<
     BinaryFunctorCrossProductPack<
         std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
         std::tuple<IntType, LongType, FloatType, DoubleType>,
-        MultiplyFunctor, PairSelectorLeft>,
+        MultiplyFunctor, meta::PairSelectorLeft>,
     BinaryFunctorCrossProductPack<
         std::tuple<IntType, LongType, FloatType, DoubleType>,
         std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
-        MultiplyFunctor, PairSelectorRight>
+        MultiplyFunctor, meta::PairSelectorRight>
 >;
 
 using DivideBinaryFunctorPack = FunctorPack<
@@ -157,7 +158,7 @@ using DivideBinaryFunctorPack = FunctorPack<
     BinaryFunctorCrossProductPack<
         std::tuple<DatetimeIntervalType, YearMonthIntervalType>,
         std::tuple<IntType, LongType, FloatType, DoubleType>,
-        DivideFunctor, PairSelectorLeft>
+        DivideFunctor, meta::PairSelectorLeft>
 >;
 
 using ModuloBinaryFunctorPack = FunctorPack<

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp b/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
index e394aa9..7181bc6 100644
--- a/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
+++ b/types/operations/binary_operations/AsciiStringBinaryOperations.hpp
@@ -33,7 +33,6 @@
 #include "types/operations/OperationUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 #include "types/port/strnlen.hpp"
-#include "utility/TemplateUtil.hpp"
 
 namespace quickstep {
 

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/BinaryOperationWrapper.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/BinaryOperationWrapper.hpp b/types/operations/binary_operations/BinaryOperationWrapper.hpp
index d1e17f3..98c2e8d 100644
--- a/types/operations/binary_operations/BinaryOperationWrapper.hpp
+++ b/types/operations/binary_operations/BinaryOperationWrapper.hpp
@@ -38,7 +38,7 @@
 #include "types/operations/OperationUtil.hpp"
 #include "types/operations/binary_operations/BinaryOperation.hpp"
 #include "utility/Macros.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -604,15 +604,15 @@ struct BinaryFunctorCrossProductPack {
 
   template <std::size_t ...Ls, std::size_t ...Rs>
   inline static std::vector<std::list<OperationPtr>> GenerateLeftHelper(
-      Sequence<Ls...> &&l_seq, Sequence<Rs...> &&r_seq) {
+      meta::IntegerSequence<Ls...> &&l_seq, meta::IntegerSequence<Rs...> &&r_seq) {
     return { GenerateRightHelper<Ls, Rs...>()... };
   }
 
   template <typename Dispatcher>
   inline static std::list<OperationPtr> GenerateOperations() {
     std::vector<std::list<OperationPtr>> op_list_groups =
-        GenerateLeftHelper(typename MakeSequence<std::tuple_size<LeftPack>::value>::type(),
-                           typename MakeSequence<std::tuple_size<RightPack>::value>::type());
+        GenerateLeftHelper(typename meta::MakeSequence<std::tuple_size<LeftPack>::value>::type(),
+                           typename meta::MakeSequence<std::tuple_size<RightPack>::value>::type());
 
     std::list<OperationPtr> operations;
     for (std::list<OperationPtr> &op_list : op_list_groups) {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMakeLists.txt b/types/operations/binary_operations/CMakeLists.txt
index 060c864..09566aa 100644
--- a/types/operations/binary_operations/CMakeLists.txt
+++ b/types/operations/binary_operations/CMakeLists.txt
@@ -38,7 +38,7 @@ add_library(quickstep_types_operations_binaryoperations_CMathBinaryOperations
 # Link dependencies:
 target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
                       quickstep_types_DateOperatorOverloads
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBinaryOperations
                       quickstep_types_DateType
                       quickstep_types_DatetimeIntervalType
@@ -53,8 +53,10 @@ target_link_libraries(quickstep_types_operations_binaryoperations_ArithmeticBina
                       quickstep_types_TypedValue
                       quickstep_types_YearMonthIntervalType
                       quickstep_types_operations_binaryoperations_ArithmeticBinaryFunctorOverloads
-                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper)
+                      quickstep_types_operations_binaryoperations_BinaryOperationWrapper
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBinaryOperations
+                      glog
                       quickstep_types_CharType
                       quickstep_types_IntType
                       quickstep_types_Type
@@ -63,9 +65,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_AsciiStringBin
                       quickstep_types_VarCharType
                       quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
-                      quickstep_types_port_strnlen
-                      quickstep_utility_TemplateUtil
-                      glog)
+                      quickstep_types_port_strnlen)
 target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_storage_StorageBlockInfo
@@ -87,7 +87,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_BinaryOperatio
                       quickstep_types_operations_OperationUtil
                       quickstep_types_operations_binaryoperations_BinaryOperation
                       quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryOperations
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
@@ -95,7 +95,7 @@ target_link_libraries(quickstep_types_operations_binaryoperations_CMathBinaryOpe
                       quickstep_types_LongType
                       quickstep_types_operations_OperationUtil
                       quickstep_types_operations_binaryoperations_BinaryOperationWrapper
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_binaryoperations ../../../empty_src.cpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/binary_operations/CMathBinaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/binary_operations/CMathBinaryOperations.hpp b/types/operations/binary_operations/CMathBinaryOperations.hpp
index 4761bfd..9a90a12 100644
--- a/types/operations/binary_operations/CMathBinaryOperations.hpp
+++ b/types/operations/binary_operations/CMathBinaryOperations.hpp
@@ -29,7 +29,7 @@
 #include "types/LongType.hpp"
 #include "types/operations/OperationUtil.hpp"
 #include "types/operations/binary_operations/BinaryOperationWrapper.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -66,9 +66,9 @@ using CMathBinaryFunctor =
 using CMathBinaryFunctorPack = FunctorPack<
 // pow
     CMathBinaryFunctor<FloatType, FloatType, FloatType,
-                       std::pow, StringLiteral<'p','o','w'>>,
+                       std::pow, meta::StringLiteral<'p','o','w'>>,
     CMathBinaryFunctor<DoubleType, DoubleType, DoubleType,
-                       std::pow, StringLiteral<'p','o','w'>>
+                       std::pow, meta::StringLiteral<'p','o','w'>>
 >;
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/comparisons/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/CMakeLists.txt b/types/operations/comparisons/CMakeLists.txt
index dcf8908..933f4fa 100644
--- a/types/operations/comparisons/CMakeLists.txt
+++ b/types/operations/comparisons/CMakeLists.txt
@@ -181,8 +181,8 @@ target_link_libraries(quickstep_types_operations_comparisons_PatternMatchingComp
                       quickstep_types_operations_comparisons_PatternMatchingComparators
                       quickstep_types_operations_comparisons_Comparison
                       quickstep_types_operations_comparisons_ComparisonID
-                      quickstep_utility_TemplateUtil
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_meta_Dispatchers)
 
 # Module all-in-one library:
 add_library(quickstep_types_operations_comparisons ../../../empty_src.cpp)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/comparisons/PatternMatchingComparison.cpp
----------------------------------------------------------------------
diff --git a/types/operations/comparisons/PatternMatchingComparison.cpp b/types/operations/comparisons/PatternMatchingComparison.cpp
index 7fa7031..c94ba52 100644
--- a/types/operations/comparisons/PatternMatchingComparison.cpp
+++ b/types/operations/comparisons/PatternMatchingComparison.cpp
@@ -29,7 +29,7 @@
 #include "types/operations/comparisons/ComparisonID.hpp"
 #include "types/operations/comparisons/PatternMatchingComparators.hpp"
 #include "types/operations/comparisons/PatternMatchingComparators-inl.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
@@ -121,7 +121,7 @@ UncheckedComparator* PatternMatchingComparison::makeUncheckedComparatorForTypes(
                  << " in PatternMatchinComparison::makeUncheckedComparatorForTypes()";
   }
 
-  return InvokeOnBools(
+  return meta::InvokeOnBools(
       is_like_pattern, is_negation,
       left.isNullable(), right.isNullable(),
       [&](auto is_like_pattern,  // NOLINT(build/c++11)

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
index 8fb2b8f..1ee1867 100644
--- a/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
+++ b/types/operations/unary_operations/AsciiStringUnaryOperations.hpp
@@ -33,7 +33,7 @@
 #include "types/operations/OperationUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
 #include "types/port/strnlen.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -96,12 +96,12 @@ struct AsciiStringTranformFunctor : public UnaryFunctor<ArgumentT, ArgumentT> {
 template <typename ArgumentT>
 using AsciiStringToLowerCaseFunctor =
     AsciiStringTranformFunctor<ArgumentT, std::tolower,
-                               StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
+                               meta::StringLiteral<'t', 'o', 'l', 'o', 'w', 'e', 'r'>>;
 
 template <typename ArgumentT>
 using AsciiStringToUpperCaseFunctor =
     AsciiStringTranformFunctor<ArgumentT, std::toupper,
-                               StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
+                               meta::StringLiteral<'t', 'o', 'u', 'p', 'p', 'e', 'r'>>;
 
 using AsciiStringUnaryFunctorPack = FunctorPack<
 // length

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/unary_operations/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMakeLists.txt b/types/operations/unary_operations/CMakeLists.txt
index e605ca7..bcd756e 100644
--- a/types/operations/unary_operations/CMakeLists.txt
+++ b/types/operations/unary_operations/CMakeLists.txt
@@ -58,7 +58,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_AsciiStringUnar
                       quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
                       quickstep_types_port_strnlen
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryOperations
                       quickstep_types_DoubleType
                       quickstep_types_FloatType
@@ -66,7 +66,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_CMathUnaryOpera
                       quickstep_types_LongType
                       quickstep_types_operations_OperationUtil
                       quickstep_types_operations_unaryoperations_UnaryOperationWrapper
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Common)
 target_link_libraries(quickstep_types_operations_unaryoperations_CastOperation
                       glog
                       quickstep_types_CharType
@@ -115,7 +115,7 @@ target_link_libraries(quickstep_types_operations_unaryoperations_SubstringOperat
                       quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_types_port_strnlen
                       quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
+                      quickstep_utility_meta_Dispatchers)
 target_link_libraries(quickstep_types_operations_unaryoperations_UnaryOperation
                       quickstep_catalog_CatalogTypedefs
                       quickstep_types_TypedValue

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/unary_operations/CMathUnaryOperations.hpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CMathUnaryOperations.hpp b/types/operations/unary_operations/CMathUnaryOperations.hpp
index 8e54c03..7a372e0 100644
--- a/types/operations/unary_operations/CMathUnaryOperations.hpp
+++ b/types/operations/unary_operations/CMathUnaryOperations.hpp
@@ -29,7 +29,7 @@
 #include "types/LongType.hpp"
 #include "types/operations/OperationUtil.hpp"
 #include "types/operations/unary_operations/UnaryOperationWrapper.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Common.hpp"
 
 namespace quickstep {
 
@@ -70,43 +70,43 @@ inline std::int64_t CMathRound(const double arg) {
 using CMathUnaryFunctorPack = FunctorPack<
 // abs
     CMathUnaryFunctor<IntType, IntType,
-                      std::abs, StringLiteral<'a','b','s'>>,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
     CMathUnaryFunctor<LongType, LongType,
-                      std::abs, StringLiteral<'a','b','s'>>,
+                      std::abs, meta::StringLiteral<'a','b','s'>>,
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::fabs, StringLiteral<'a','b','s'>>,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::fabs, StringLiteral<'a','b','s'>>,
+                      std::fabs, meta::StringLiteral<'a','b','s'>>,
 // sqrt
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::sqrt, StringLiteral<'s','q','r','t'>>,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::sqrt, StringLiteral<'s','q','r','t'>>,
+                      std::sqrt, meta::StringLiteral<'s','q','r','t'>>,
 // exp
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::exp, StringLiteral<'e','x','p'>>,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::exp, StringLiteral<'e','x','p'>>,
+                      std::exp, meta::StringLiteral<'e','x','p'>>,
 // log
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::log, StringLiteral<'l','o','g'>>,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::log, StringLiteral<'l','o','g'>>,
+                      std::log, meta::StringLiteral<'l','o','g'>>,
 // ceil
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::ceil, StringLiteral<'c','e','i','l'>>,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::ceil, StringLiteral<'c','e','i','l'>>,
+                      std::ceil, meta::StringLiteral<'c','e','i','l'>>,
 // floor
     CMathUnaryFunctor<FloatType, FloatType,
-                      std::floor, StringLiteral<'f','l','o','o','r'>>,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
     CMathUnaryFunctor<DoubleType, DoubleType,
-                      std::floor, StringLiteral<'f','l','o','o','r'>>,
+                      std::floor, meta::StringLiteral<'f','l','o','o','r'>>,
 // round
     CMathUnaryFunctor<FloatType, LongType,
-                      CMathRound, StringLiteral<'r','o','u','n','d'>>,
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>,
     CMathUnaryFunctor<DoubleType, LongType,
-                      CMathRound, StringLiteral<'r','o','u','n','d'>>
+                      CMathRound, meta::StringLiteral<'r','o','u','n','d'>>
 >;
 
 /** @} */

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/unary_operations/CastOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/CastOperation.cpp b/types/operations/unary_operations/CastOperation.cpp
index 21378e4..3e0ed56 100644
--- a/types/operations/unary_operations/CastOperation.cpp
+++ b/types/operations/unary_operations/CastOperation.cpp
@@ -195,7 +195,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
     return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>(
         argument_type_id,
         [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeClass<decltype(arg_tid)::value>::type;
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
 
       switch (result_type_id) {
         case kInt:  // Fall through
@@ -205,7 +205,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeClass<decltype(result_tid)::value>::type;
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                 NumericCastToNumericFunctor<ArgumentT, ResultT>>(type, *result_type);
@@ -216,7 +216,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeClass<decltype(result_tid)::value>::type;
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                  CastToAsciiStringFunctor<ArgumentT, ResultT>>(
@@ -235,7 +235,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
     return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
         argument_type_id,
         [&](auto arg_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-      using ArgumentT = typename TypeClass<decltype(arg_tid)::value>::type;
+      using ArgumentT = typename TypeIDTrait<decltype(arg_tid)::value>::TypeClass;
 
       switch (result_type_id) {
         case kInt:  // Fall through
@@ -245,7 +245,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kInt, kLong, kFloat, kDouble>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeClass<decltype(result_tid)::value>::type;
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                 AsciiStringCastToNumericFunctor<
@@ -260,7 +260,7 @@ UncheckedUnaryOperator* CastOperation::makeUncheckedUnaryOperator(
           return InvokeOnTypeID<TypeIDSelectorEqualsAny<kChar, kVarChar>>(
               result_type_id,
               [&](auto result_tid) -> UncheckedUnaryOperator* {  // NOLINT(build/c++11)
-            using ResultT = typename TypeClass<decltype(result_tid)::value>::type;
+            using ResultT = typename TypeIDTrait<decltype(result_tid)::value>::TypeClass;
 
             return new UncheckedUnaryOperatorWrapperCodegen<
                  AsciiStringCastToAsciiStringFunctor<ArgumentT, ResultT>>(

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/types/operations/unary_operations/SubstringOperation.cpp
----------------------------------------------------------------------
diff --git a/types/operations/unary_operations/SubstringOperation.cpp b/types/operations/unary_operations/SubstringOperation.cpp
index 2693194..1cc8912 100644
--- a/types/operations/unary_operations/SubstringOperation.cpp
+++ b/types/operations/unary_operations/SubstringOperation.cpp
@@ -25,7 +25,7 @@
 #include "types/Type.hpp"
 #include "types/TypeID.hpp"
 #include "types/TypedValue.hpp"
-#include "utility/TemplateUtil.hpp"
+#include "utility/meta/Dispatchers.hpp"
 
 #include "glog/logging.h"
 
@@ -49,7 +49,7 @@ UncheckedUnaryOperator* SubstringOperation::makeUncheckedUnaryOperator(
   const Type *result_type = getResultType(type, static_arguments);
   DCHECK(result_type != nullptr);
 
-  return InvokeOnBools(
+  return meta::InvokeOnBools(
       input_null_terminated, type.isNullable(),
       [&](auto is_null_terminated,  // NOLINT(build/c++11)
           auto is_nullable) -> UncheckedUnaryOperator* {

http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/d70a6397/utility/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/utility/CMakeLists.txt b/utility/CMakeLists.txt
index ca04462..56d80e3 100644
--- a/utility/CMakeLists.txt
+++ b/utility/CMakeLists.txt
@@ -159,6 +159,7 @@ QS_PROTOBUF_GENERATE_CPP(quickstep_utility_SortConfiguration_proto_srcs
                          SortConfiguration.proto)
 
 add_subdirectory(lip_filter)
+add_subdirectory(meta)
 
 # Declare micro-libs:
 add_library(quickstep_utility_Alignment ../empty_src.cpp Alignment.hpp)
@@ -200,7 +201,6 @@ add_library(quickstep_utility_SortConfiguration_proto
             ${quickstep_utility_SortConfiguration_proto_hdrs})
 add_library(quickstep_utility_SqlError SqlError.cpp SqlError.hpp)
 add_library(quickstep_utility_StringUtil StringUtil.cpp StringUtil.hpp)
-add_library(quickstep_utility_TemplateUtil ../empty_src.cpp TemplateUtil.hpp)
 # Note that TextBasedTest.{hpp, cpp} are not in this static library.
 # Any tests that use them need to include them in the
 # executable.
@@ -318,7 +318,6 @@ target_link_libraries(quickstep_utility_ShardedLockManager
                       quickstep_utility_Macros)
 target_link_libraries(quickstep_utility_StringUtil
                       glog)
-target_link_libraries(quickstep_utility_TemplateUtil)
 target_link_libraries(quickstep_utility_TextBasedTestDriver
                       glog
                       gtest
@@ -366,7 +365,6 @@ target_link_libraries(quickstep_utility
                       quickstep_utility_SortConfiguration_proto
                       quickstep_utility_SqlError
                       quickstep_utility_StringUtil
-                      quickstep_utility_TemplateUtil
                       quickstep_utility_TextBasedTestDriver
                       quickstep_utility_ThreadSafeQueue
                       quickstep_utility_TreeStringSerializable
@@ -478,14 +476,6 @@ target_link_libraries(TreeStringSerializable_unittest
                       quickstep_utility_TreeStringSerializable)
 add_test(TreeStringSerializable_unittest TreeStringSerializable_unittest)
 
-add_executable(TemplateUtil_unittest "${CMAKE_CURRENT_SOURCE_DIR}/tests/TemplateUtil_unittest.cpp")
-target_link_libraries(TemplateUtil_unittest
-                      gtest
-                      gtest_main
-                      quickstep_utility_Macros
-                      quickstep_utility_TemplateUtil)
-add_test(TemplateUtil_unittest TemplateUtil_unittest)
-
 # Benchmarks:
 if (UNIX)
   add_executable(EqualsAnyConstant_benchmark