http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/types/operations/utility/OperationSynthesizeUtil.hpp ---------------------------------------------------------------------- diff --git a/types/operations/utility/OperationSynthesizeUtil.hpp b/types/operations/utility/OperationSynthesizeUtil.hpp new file mode 100644 index 0000000..2b910b3 --- /dev/null +++ b/types/operations/utility/OperationSynthesizeUtil.hpp @@ -0,0 +1,335 @@ +/** + * 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_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_ +#define QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_ + +#include <cstddef> +#include <list> +#include <string> +#include <type_traits> + +#include "catalog/CatalogTypedefs.hpp" +#include "types/Type.hpp" +#include "types/TypedValue.hpp" +#include "types/containers/ColumnVector.hpp" + +namespace quickstep { + +/** \addtogroup Types + * @{ + */ + +template <typename FunctorT, typename ...SpecArgs> +struct FunctorSpecializer { + template <bool specialize = (sizeof...(SpecArgs) != 0), + typename EnableT = void> + struct Implementation; + + typedef Implementation<> type; +}; + +template <typename FunctorT, typename ...SpecArgs> +template <bool specialize> +struct FunctorSpecializer<FunctorT, SpecArgs...> + ::Implementation<specialize, std::enable_if_t<specialize>> { + template <typename ...FuncArgs> + inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) { + return functor.template apply<SpecArgs...>(std::forward<FuncArgs>(args)...); + } + typedef FunctorT FunctorType; +}; + +template <typename FunctorT, typename ...SpecArgs> +template <bool specialize> +struct FunctorSpecializer<FunctorT, SpecArgs...> + ::Implementation<specialize, std::enable_if_t<!specialize>> { + template <typename ...FuncArgs> + inline static auto Invoke(const FunctorT &functor, FuncArgs &&...args) { + return functor.apply(std::forward<FuncArgs>(args)...); + } + typedef FunctorT FunctorType; +}; + +template <typename ColumnVectorT> +struct ColumnVectorValueAccessor { + explicit ColumnVectorValueAccessor(const ColumnVectorT &column_vector_in) + : column_vector(column_vector_in), + length(column_vector.size()) {} + + inline void beginIteration() { + pos = static_cast<std::size_t>(-1); + } + + inline bool next() { + return (++pos) < length; + } + + inline std::size_t getNumTuples() const { + return length; + } + + template <bool nullable> + inline const void* getUntypedValue(const attribute_id) const { + return column_vector.template getUntypedValue<nullable>(pos); + } + + inline TypedValue getTypedValue(const attribute_id) const { + return column_vector.getTypedValue(pos); + } + + const ColumnVectorT &column_vector; + const std::size_t length; + std::size_t pos; +}; + +template <typename FuncSpec, typename T, typename EnableT = void> +struct OperationCodegen; + +template <typename FuncSpec, typename T> +struct OperationCodegen<FuncSpec, T, + std::enable_if_t<T::kMemoryLayout == kCxxInlinePod>> { + using ColumnVectorType = NativeColumnVector; + using FunctorSpecializer = FuncSpec; + + using NativeType = typename T::cpptype; + using NativeTypeConst = const typename T::cpptype; + using NativeTypeConstRef = const NativeType&; + using NativeTypeConstPtr = const NativeType*; + + template <typename ArgumentGen> + inline static TypedValue ApplyUnaryTypedValue( + typename ArgumentGen::NativeTypeConstRef argument, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + return TypedValue(FuncSpec::Invoke(functor, argument)); + } + + template <typename ArgumentGen> + inline static void ApplyUnaryColumnVector( + const typename ArgumentGen::NativeTypeConstRef argument, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + *static_cast<NativeType *>(cv->getPtrForDirectWrite()) = + FuncSpec::Invoke(functor, argument); + } + + template <typename LeftGen, typename RightGen> + inline static TypedValue ApplyBinaryTypedValue( + typename LeftGen::NativeTypeConstRef left, + typename RightGen::NativeTypeConstRef right, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + return TypedValue(FuncSpec::Invoke(functor, left, right)); + } + + template <typename LeftGen, typename RightGen> + inline static void ApplyBinaryColumnVector( + const typename LeftGen::NativeTypeConstRef left, + const typename RightGen::NativeTypeConstRef right, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + *static_cast<NativeType *>(cv->getPtrForDirectWrite()) = + FuncSpec::Invoke(functor, left, right); + } + + template <bool nullable, typename AccessorT> + inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor, + const attribute_id attr_id) { + return static_cast<NativeTypeConstPtr>( + accessor->template getUntypedValue<nullable>(attr_id)); + } + + inline static bool IsNull(const NativeType *value) { + return value == nullptr; + } + + // Dereference: NativeTypeConstPtr& -> const NativeType& + inline static const NativeType& Dereference(const NativeType *value) { + return *value; + } + + inline static const NativeType ToNativeValueConst(const TypedValue &value) { + return value.getLiteral<NativeType>(); + } +}; + +template <typename FuncSpec, typename T> +struct OperationCodegen<FuncSpec, T, + std::enable_if_t<T::kMemoryLayout == kParInlinePod>> { + using ColumnVectorType = NativeColumnVector; + using FunctorSpecializer = FuncSpec; + + using NativeType = const void*; + using NativeTypeConst = const void*; + using NativeTypeConstRef = const void*; + using NativeTypeConstPtr = const void*; + + template <typename ArgumentGen> + inline static TypedValue ApplyUnaryTypedValue( + typename ArgumentGen::NativeTypeConstRef argument, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + void *result = std::malloc(result_type.maximumByteLength()); + FuncSpec::Invoke(functor, argument, result); + return TypedValue::CreateWithOwnedData(T::kStaticTypeID, + result, + result_type.maximumByteLength()); + } + + template <typename ArgumentGen> + inline static void ApplyUnaryColumnVector( + const typename ArgumentGen::NativeTypeConstRef argument, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + FuncSpec::Invoke(functor, argument, cv->getPtrForDirectWrite()); + } + + template <typename LeftGen, typename RightGen> + inline static TypedValue ApplyBinaryTypedValue( + typename LeftGen::NativeTypeConstRef left, + typename RightGen::NativeTypeConstRef right, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + void *result = std::malloc(result_type.maximumByteLength()); + FuncSpec::Invoke(functor, left, right, result); + return TypedValue::CreateWithOwnedData(T::kStaticTypeID, + result, + result_type.maximumByteLength()); + } + + template <typename LeftGen, typename RightGen> + inline static void ApplyBinaryColumnVector( + const typename LeftGen::NativeTypeConstRef left, + const typename RightGen::NativeTypeConstRef right, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + FuncSpec::Invoke(functor, left, right, cv->getPtrForDirectWrite()); + } + + template <bool nullable, typename AccessorT> + inline static NativeTypeConstPtr GetValuePtr(const AccessorT *accessor, + const attribute_id attr_id) { + return accessor->template getUntypedValue<nullable>(attr_id); + } + + inline static bool IsNull(const void *value) { + return value == nullptr; + } + + // Dereference: NativeTypeConstPtr& -> const NativeType& + inline static const void* Dereference(const void *value) { + return value; + } + + inline static const void* ToNativeValueConst(const TypedValue &value) { + return value.getDataPtr(); + } +}; + +template <typename FuncSpec, typename T> +struct OperationCodegen<FuncSpec, T, + std::enable_if_t<T::kMemoryLayout == kParOutOfLinePod>> { + using ColumnVectorType = IndirectColumnVector; + using FunctorSpecializer = FuncSpec; + + using NativeType = TypedValue; + using NativeTypeConst = const TypedValue; + using NativeTypeConstRef = const TypedValue&; + using NativeTypeConstPtr = const TypedValue; + + template <typename ArgumentGen> + inline static TypedValue ApplyUnaryTypedValue( + typename ArgumentGen::NativeTypeConstRef argument, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + return FuncSpec::Invoke(functor, argument); + } + + template <typename ArgumentGen> + inline static void ApplyUnaryColumnVector( + const typename ArgumentGen::NativeTypeConstRef argument, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + cv->appendTypedValue(FuncSpec::Invoke(functor, argument)); + } + + template <typename LeftGen, typename RightGen> + inline static TypedValue ApplyBinaryTypedValue( + typename LeftGen::NativeTypeConstRef left, + typename RightGen::NativeTypeConstRef right, + const Type &result_type, + const typename FuncSpec::FunctorType &functor) { + return FuncSpec::Invoke(functor, left, right); + } + + template <typename LeftGen, typename RightGen> + inline static void ApplyBinaryColumnVector( + const typename LeftGen::NativeTypeConstRef left, + const typename RightGen::NativeTypeConstRef right, + const typename FuncSpec::FunctorType &functor, + ColumnVectorType *cv) { + cv->appendTypedValue(FuncSpec::Invoke(functor, left, right)); + } + + template <bool nullable, typename AccessorT> + inline static NativeTypeConstPtr GetValuePtr( + const AccessorT *accessor, + const attribute_id attr_id) { + return accessor->getTypedValue(attr_id); + } + + inline static bool IsNull(NativeTypeConstPtr &value) { + return value.isNull(); + } + + // Dereference: NativeTypeConstPtr& -> const NativeType& + inline static const NativeType& Dereference(NativeTypeConstPtr &value) { + return value; + } + + inline static const NativeType& ToNativeValueConst(const TypedValue &value) { + return value; + } +}; + +template <typename ...FunctorTypes> +struct FunctorPack { + template <typename Dispatcher> + inline static std::list<OperationPtr> GenerateOperations() { + std::vector<std::list<OperationPtr>> op_list_groups = + { Dispatcher::template Generate<FunctorTypes>()... }; + + std::list<OperationPtr> operations; + for (std::list<OperationPtr> &op_list : op_list_groups) { + operations.splice(operations.end(), std::move(op_list)); + } + return operations; + } +}; + +struct OperationPack { + virtual std::vector<OperationPtr> generateOperations() = 0; +}; + +/** @} */ + +} // namespace quickstep + +#endif // QUICKSTEP_TYPES_OPERATIONS_OPERATION_SYNTHESIZE_UTIL_HPP_
http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/Common.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/Common.hpp b/utility/meta/Common.hpp index 901b65c..cbad665 100644 --- a/utility/meta/Common.hpp +++ b/utility/meta/Common.hpp @@ -23,7 +23,7 @@ namespace quickstep { namespace meta { -/** \addtogroup Utility +/** \addtogroup Meta * @{ */ @@ -99,6 +99,19 @@ struct IsWellFormed<T, Op, std::enable_if_t<std::is_same<Op<T>, Op<T>>::value>> }; +namespace internal { + +template <typename T, std::size_t = sizeof(T)> +std::true_type IsCompleteTypeImpl(T *); + +std::false_type IsCompleteTypeImpl(...); + +} // namespace internal + +template <typename T> +using IsCompleteType = decltype(internal::IsCompleteTypeImpl(std::declval<T*>())); + + template <typename LeftT, typename RightT> struct PairSelectorLeft { typedef LeftT type; http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/Dispatchers.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/Dispatchers.hpp b/utility/meta/Dispatchers.hpp index 5b0ee48..1624bea 100644 --- a/utility/meta/Dispatchers.hpp +++ b/utility/meta/Dispatchers.hpp @@ -25,7 +25,7 @@ namespace quickstep { namespace meta { -/** \addtogroup Utility +/** \addtogroup Meta * @{ */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/MetaprogrammingModule.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/MetaprogrammingModule.hpp b/utility/meta/MetaprogrammingModule.hpp new file mode 100644 index 0000000..912fdef --- /dev/null +++ b/utility/meta/MetaprogrammingModule.hpp @@ -0,0 +1,24 @@ +/** + * 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. + **/ + +/** @defgroup Meta + * @ingroup Utility + * + * Template metaprogramming utilities. + **/ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/TransitiveClosure.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/TransitiveClosure.hpp b/utility/meta/TransitiveClosure.hpp index a5362bb..d5bb0ca 100644 --- a/utility/meta/TransitiveClosure.hpp +++ b/utility/meta/TransitiveClosure.hpp @@ -25,7 +25,7 @@ namespace quickstep { namespace meta { -/** \addtogroup Utility +/** \addtogroup Meta * @{ */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/TypeList.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/TypeList.hpp b/utility/meta/TypeList.hpp index fac3ce5..5f4c4d9 100644 --- a/utility/meta/TypeList.hpp +++ b/utility/meta/TypeList.hpp @@ -26,15 +26,19 @@ namespace quickstep { namespace meta { -/** \addtogroup Utility +/** \addtogroup Meta * @{ */ template <typename ...Ts> class TypeList; +namespace internal { + +using EmptyList = TypeList<>; + template <typename ...Ts> -class TypeListCommon { +class TypeListBase { private: template <typename ...Tail> struct AppendHelper { using type = TypeList<Ts..., Tail...>; @@ -44,13 +48,20 @@ class TypeListCommon { static constexpr std::size_t length = sizeof...(Ts); using type = TypeList<Ts...>; + using self = type; 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; + using at = typename ElementAtImpl< + self, TypeList<std::integral_constant<std::size_t, pos>...>>::type; + + template <std::size_t n> + using take = typename TakeImpl<self, EmptyList, n>::type; + + template <std::size_t n> + using skip = typename SkipImpl<self, n>::type; template <typename T> using push_front = TypeList<T, Ts...>; @@ -62,59 +73,59 @@ class TypeListCommon { using contains = EqualsAny<T, Ts...>; template <typename ...DumbT> - using unique = typename internal::UniqueImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type; + using unique = typename UniqueImpl<EmptyList, self, 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; + using cartesian_product = typename CartesianProductImpl<self, TL>::type; template <typename Subtrahend> - using subtract = typename internal::SubtractImpl<TypeList<>, TypeList<Ts...>, Subtrahend>::type; + using subtract = typename SubtractImpl<EmptyList, self, 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; + using flatmap = typename FlatmapImpl<EmptyList, self, Op>::type; template <template <typename ...> class Op> - using filter = typename internal::FilterImpl<TypeList<>, TypeList<Ts...>, Op>::type; + using filter = typename FilterImpl<EmptyList, self, Op>::type; template <template <typename ...> class Op> - using filtermap = typename internal::FiltermapImpl<TypeList<>, TypeList<Ts...>, Op>::type; + using filtermap = typename FiltermapImpl<EmptyList, self, Op>::type; + + template <typename ...DumbT> + using flatten = typename FlattenImpl<EmptyList, self, DumbT...>::type; template <typename ...DumbT> - using flatten_once = typename internal::FlattenOnceImpl<TypeList<>, TypeList<Ts...>, DumbT...>::type; + using flatten_once = typename FlattenOnceImpl<EmptyList, self, DumbT...>::type; + + template <template <typename ...> class Op, typename InitT> + using foldl = typename FoldlImpl<InitT, self, Op>::type; template <typename TL> - using zip = typename internal::ZipImpl<TypeList<>, TypeList<Ts...>, TL>::type; + using zip = typename ZipImpl<EmptyList, self, TL>::type; template <typename TL, template <typename ...> class Op> - using zip_with = typename internal::ZipWithImpl<TypeList<>, TypeList<Ts...>, TL, Op>::type; + using zip_with = typename ZipWithImpl<EmptyList, self, TL, Op>::type; template <typename T> - using as_sequence = typename internal::AsSequenceImpl<T, Ts...>::type; + using as_sequence = typename AsSequenceImpl<T, Ts...>::type; }; -template <typename ...Ts> -class TypeList : public TypeListCommon<Ts...> { - private: - template <typename Head, typename ...Tail> - struct HeadTailHelper { - using head = Head; - using tail = TypeList<Tail...>; - }; +} // namespace internal +template <typename T, typename ...Ts> +class TypeList<T, Ts...> : public internal::TypeListBase<T, Ts...> { public: - using head = typename HeadTailHelper<Ts...>::head; - using tail = typename HeadTailHelper<Ts...>::tail; + using head = T; + using tail = TypeList<Ts...>; }; template <> -class TypeList<> : public TypeListCommon<> { -}; +class TypeList<> : public internal::TypeListBase<> {}; /** @} */ http://git-wip-us.apache.org/repos/asf/incubator-quickstep/blob/1cb97e35/utility/meta/TypeListMetaFunctions.hpp ---------------------------------------------------------------------- diff --git a/utility/meta/TypeListMetaFunctions.hpp b/utility/meta/TypeListMetaFunctions.hpp index d908493..baebe91 100644 --- a/utility/meta/TypeListMetaFunctions.hpp +++ b/utility/meta/TypeListMetaFunctions.hpp @@ -25,13 +25,24 @@ namespace quickstep { namespace meta { -/** \addtogroup Utility +/** \addtogroup Meta * @{ */ template <typename ...Ts> class TypeList; + +template <typename T> +struct IsTypeList { + constexpr static bool value = false; +}; +template <typename ...Ts> +struct IsTypeList<TypeList<Ts...>> { + constexpr static bool value = true; +}; + + namespace internal { template <typename TL, typename PosTL, typename Enable = void> @@ -52,6 +63,34 @@ struct ElementAtImpl<TL, PosTL, typename PosTL::tail> {}; +template <typename TL, typename Out, std::size_t rest, typename Enable = void> +struct TakeImpl; + +template <typename TL, typename Out, std::size_t rest> +struct TakeImpl<TL, Out, rest, std::enable_if_t<rest == 0>> { + using type = Out; +}; + +template <typename TL, typename Out, std::size_t rest> +struct TakeImpl<TL, Out, rest, std::enable_if_t<rest != 0>> + : TakeImpl<typename TL::tail, + typename Out::template push_back<typename TL::head>, + rest - 1> {}; + + +template <typename TL, std::size_t rest, typename Enable = void> +struct SkipImpl; + +template <typename TL, std::size_t rest> +struct SkipImpl<TL, rest, std::enable_if_t<rest == 0>> { + using type = TL; +}; + +template <typename TL, std::size_t rest> +struct SkipImpl<TL, rest, std::enable_if_t<rest != 0>> + : SkipImpl<typename TL::tail, rest - 1> {}; + + template <typename Out, typename Rest, typename Enable = void> struct UniqueImpl; @@ -174,6 +213,30 @@ struct FiltermapImpl<Out, Rest, Op, template <typename Out, typename Rest, typename Enable = void> +struct FlattenImpl; + +template <typename Out, typename Rest> +struct FlattenImpl<Out, Rest, + std::enable_if_t<Rest::length == 0>> { + using type = Out; +}; + +template <typename Out, typename Rest> +struct FlattenImpl<Out, Rest, + std::enable_if_t<Rest::length != 0 && + IsTypeList<typename Rest::head>::value>> + : FlattenImpl<typename Out::template append<typename Rest::head::template flatten<>>, + typename Rest::tail> {}; + +template <typename Out, typename Rest> +struct FlattenImpl<Out, Rest, + std::enable_if_t<Rest::length != 0 && + !IsTypeList<typename Rest::head>::value>> + : FlattenImpl<typename Out::template push_back<typename Rest::head>, + typename Rest::tail> {}; + + +template <typename Out, typename Rest, typename Enable = void> struct FlattenOnceImpl; template <typename Out, typename Rest> @@ -188,6 +251,21 @@ struct FlattenOnceImpl<Out, Rest, : FlattenOnceImpl<typename Out::template append<typename Rest::head>, typename Rest::tail> {}; +template <typename Out, typename Rest, template <typename ...> class Op, + typename Enable = void> +struct FoldlImpl; + +template <typename Out, typename Rest, template <typename ...> class Op> +struct FoldlImpl<Out, Rest, Op, + std::enable_if_t<Rest::length == 0>> { + using type = Out; +}; + +template <typename Out, typename Rest, template <typename ...> class Op> +struct FoldlImpl<Out, Rest, Op, + std::enable_if_t<Rest::length != 0>> + : FoldlImpl<typename Op<Out, typename Rest::head>::type, + typename Rest::tail, Op> {}; template <typename Out, typename RestL, typename RestR, typename Enable = void> struct ZipImpl;
