diff options
Diffstat (limited to 'libcilkrts/include/cilk/metaprogramming.h')
-rw-r--r-- | libcilkrts/include/cilk/metaprogramming.h | 107 |
1 files changed, 61 insertions, 46 deletions
diff --git a/libcilkrts/include/cilk/metaprogramming.h b/libcilkrts/include/cilk/metaprogramming.h index 29b0839e788..2df7cf6467c 100644 --- a/libcilkrts/include/cilk/metaprogramming.h +++ b/libcilkrts/include/cilk/metaprogramming.h @@ -1,10 +1,8 @@ /* metaprogramming.h -*- C++ -*- * - * @copyright - * Copyright (C) 2012-2013, Intel Corporation + * Copyright (C) 2012-2016, Intel Corporation * All rights reserved. * - * @copyright * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -19,7 +17,6 @@ * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * - * @copyright * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -32,11 +29,25 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + * + * ********************************************************************* + * + * PLEASE NOTE: This file is a downstream copy of a file mainitained in + * a repository at cilkplus.org. Changes made to this file that are not + * submitted through the contribution process detailed at + * http://www.cilkplus.org/submit-cilk-contribution will be lost the next + * time that a new version is released. Changes only submitted to the + * GNU compiler collection or posted to the git repository at + * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are + * not tracked. + * + * We welcome your contributions to this open source project. Thank you + * for your assistance in helping us improve Cilk Plus. */ /** @file metaprogramming.h * - * @brief Defines metaprogramming utility classes used in the Cilk library. + * @brief Defines metaprogramming utility classes used in the Intel(R) Cilk(TM) Plus library. * * @ingroup common */ @@ -61,7 +72,7 @@ namespace internal { /** Test if a class is empty. * * If @a Class is an empty (and therefore necessarily stateless) class, then - * the “empty base-class optimization” guarantees that + * the "empty base-class optimization" guarantees that * `sizeof(check_for_empty_class<Class>) == sizeof(char)`. Conversely, if * `sizeof(check_for_empty_class<Class>) > sizeof(char)`, then @a Class is not * empty, and we must discriminate distinct instances of @a Class. @@ -84,7 +95,7 @@ namespace internal { * @ingroup common */ template <class Class> -class class_is_empty { +class class_is_empty { class check_for_empty_class : public Class { char m_data; @@ -147,11 +158,11 @@ public: * @tparam Size The required minimum size of the resulting class. * @tparam Alignment The required alignment of the resulting class. * - * @pre @a Alignment shall be a power of 2 no greater then 64. + * @pre @a Alignment shall be a power of 2 no greater than 64. * * @note This is implemented using the `CILK_ALIGNAS` macro, which uses * the non-standard, implementation-specific features - * `__declspec(align(N))` on Windows, and + * `__declspec(align(N))` on Windows, and * `__attribute__((__aligned__(N)))` on Unix. The `gcc` implementation * of `__attribute__((__aligned__(N)))` requires a numeric literal `N` * (_not_ an arbitrary compile-time constant expression). Therefore, @@ -165,21 +176,22 @@ public: template <std::size_t Size, std::size_t Alignment> struct aligned_storage; -template<std::size_t Size> class aligned_storage<Size, 1> +/// @cond +template<std::size_t Size> class aligned_storage<Size, 1> { CILK_ALIGNAS( 1) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 2> +template<std::size_t Size> class aligned_storage<Size, 2> { CILK_ALIGNAS( 2) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 4> +template<std::size_t Size> class aligned_storage<Size, 4> { CILK_ALIGNAS( 4) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 8> +template<std::size_t Size> class aligned_storage<Size, 8> { CILK_ALIGNAS( 8) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 16> +template<std::size_t Size> class aligned_storage<Size, 16> { CILK_ALIGNAS(16) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 32> +template<std::size_t Size> class aligned_storage<Size, 32> { CILK_ALIGNAS(32) char m_bytes[Size]; }; -template<std::size_t Size> class aligned_storage<Size, 64> +template<std::size_t Size> class aligned_storage<Size, 64> { CILK_ALIGNAS(64) char m_bytes[Size]; }; - +/// @endcond /** A buffer of uninitialized bytes with the same size and alignment as a * specified type. @@ -188,14 +200,14 @@ template<std::size_t Size> class aligned_storage<Size, 64> * properties as `Type`, but it will contain only raw (uninitialized) bytes. * This allows the definition of a data member which can contain a `Type` * object which is initialized explicitly under program control, rather - * than implicitly as part of the initialization of the containing class. + * than implicitly as part of the initialization of the containing class. * For example: * * class C { * storage_for_object<MemberClass> _member; * public: * C() ... // Does NOT initialize _member - * void initialize(args) + * void initialize(args) * { new (_member.pointer()) MemberClass(args); } * const MemberClass& member() const { return _member.object(); } * MemberClass& member() { return _member.object(); } @@ -204,21 +216,22 @@ template<std::size_t Size> class aligned_storage<Size, 64> * by this class. */ template <typename Type> -class storage_for_object : +class storage_for_object : aligned_storage< sizeof(Type), align_of<Type>::value > { public: /// Return a typed reference to the buffer. const Type& object() const { return *reinterpret_cast<Type*>(this); } + /// Return a typed reference to the buffer. Type& object() { return *reinterpret_cast<Type*>(this); } }; /** Get the functor class corresponding to a binary function type. * - * The `binary_functor` template class class can be instantiated with a binary + * The `binary_functor` template class can be instantiated with a binary * functor class or with a real binary function, and will yield an equivalent - * binary functor class class in either case. + * binary functor class in either case. * * @tparam F A binary functor class, a binary function type, or a pointer to * binary function type. @@ -260,7 +273,7 @@ struct binary_functor<R(*)(A,B)> { * `typed_indirect_binary_function<F>` is an `Adaptable Binary Function` class * based on an existing binary functor class or binary function type @a F. If * @a F is a stateless class, then this class will be empty, and its - * `operator()` will invoke @a F’s `operator()`. Otherwise, an object of this + * `operator()` will invoke @a F's `operator()`. Otherwise, an object of this * class will hold a pointer to an object of type @a F, and will refer its * `operator()` calls to the pointed-to @a F object. * @@ -276,14 +289,15 @@ struct binary_functor<R(*)(A,B)> { * * @note Just to repeat: if `F` is an empty class, then * `typed_indirect_binary_function\<F\>' is also an empty class. - * This is critical for its use in the @ref min_max::view_base + * This is critical for its use in the + * @ref cilk::cilk_lib_1_1::min_max_internal::view_base * "min/max reducer view classes", where it allows the view to * call a comparison functor in the monoid without actually - * having to allocate a pointer in the view class when the + * having to allocate a pointer in the view class when the * comparison class is empty. * * @note If you have an `Adaptable Binary Function` class or a binary - * function type, then you can use the + * function type, then you can use the * @ref indirect_binary_function class, which derives the * argument and result types parameter type instead of requiring * you to specify them as template arguments. @@ -312,7 +326,7 @@ class typed_indirect_binary_function : std::binary_function<A1, A2, R> public: /// Constructor captures a pointer to the wrapped function. typed_indirect_binary_function(const F* f) : f(f) {} - + /// Return the comparator pointer, or `NULL` if the comparator is stateless. const F* pointer() const { return f; } @@ -323,10 +337,10 @@ public: /// @copydoc typed_indirect_binary_function /// Specialization for an empty functor class. (This is only possible if @a F -/// itself is an empty class. If @a F is a function or pointer-to-function +/// itself is an empty class. If @a F is a function or pointer-to-function /// type, then the functor will contain a pointer.) template <typename F, typename A1, typename A2, typename R, typename Functor> -class typed_indirect_binary_function<F, A1, A2, R, Functor, true> : +class typed_indirect_binary_function<F, A1, A2, R, Functor, true> : std::binary_function<A1, A2, R> { public: @@ -335,7 +349,7 @@ public: /// Constructor discards the pointer to a stateless functor class. typed_indirect_binary_function(const F* f) {} - + /// Create an instance of the stateless functor class and apply it to the arguments. R operator()(const A1& a1, const A2& a2) const { return F()(a1, a2); } }; @@ -343,28 +357,29 @@ public: /** Indirect binary function class with inferred types. * - * This is identical to @ref typed_indirect_binary_function, except that it - * derives the binary function argument and result types from the parameter - * type @a F instead of taking them as additional template parameters. If @a F - * is a class type, then it must be an `Adaptable Binary Function`. + * This is identical to @ref cilk::internal::typed_indirect_binary_function, + * except that it derives the binary function argument and result types from + * the parameter type @a F instead of taking them as additional template + * parameters. If @a F is a class type, then it must be an `Adaptable Binary + * Function`. * * @see typed_indirect_binary_function * * @ingroup common */ template <typename F, typename Functor = typename binary_functor<F>::type> -class indirect_binary_function : +class indirect_binary_function : typed_indirect_binary_function< F , typename Functor::first_argument_type , typename Functor::second_argument_type , typename Functor::result_type - > + > { typedef typed_indirect_binary_function< F , typename Functor::first_argument_type , typename Functor::second_argument_type , typename Functor::result_type - > + > base; public: indirect_binary_function(const F* f) : base(f) {} ///< Constructor @@ -373,7 +388,7 @@ public: /** Choose a type based on a boolean constant. * - * This metafunction is identical to C++11’s condition metafunction. + * This metafunction is identical to C++11's condition metafunction. * It needs to be here until we can reasonably assume that users will be * compiling with C++11. * @@ -407,12 +422,12 @@ struct condition<false, IfTrue, IfFalse> * Causes a compilation error if a compile-time constant expression is false. * * @par Usage example. - * This assertion is used in reducer_min_max.h to avoid defining + * This assertion is used in reducer_min_max.h to avoid defining * legacy reducer classes that would not be binary-compatible with the * same classes compiled with earlier versions of the reducer library. * * __CILKRTS_STATIC_ASSERT( - * internal::class_is_empty< internal::binary_functor<Compare> >::value, + * internal::class_is_empty< internal::binary_functor<Compare> >::value, * "cilk::reducer_max<Value, Compare> only works with an empty Compare class"); * * @note In a C++11 compiler, this is just the language predefined @@ -468,13 +483,13 @@ inline void* allocate_aligned(std::size_t size, std::size_t alignment) #ifdef _WIN32 return _aligned_malloc(size, alignment); #else -#if defined(__ANDROID__) +#if defined(__ANDROID__) || defined(__VXWORKS__) return memalign(std::max(alignment, sizeof(void*)), size); #else void* ptr; return (posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0) ? ptr : 0; #endif -#endif +#endif } /** Implementation-specific aligned memory deallocation function. @@ -487,13 +502,13 @@ inline void deallocate_aligned(void* ptr) _aligned_free(ptr); #else std::free(ptr); -#endif +#endif } /** Class to allocate and guard an aligned pointer. * * A new_aligned_pointer object allocates aligned heap-allocated memory when - * it is created, and automatically deallocates it when it is destroyed + * it is created, and automatically deallocates it when it is destroyed * unless its `ok()` function is called. * * @tparam T The type of the object to allocate on the heap. The allocated @@ -504,14 +519,14 @@ class new_aligned_pointer { void* m_ptr; public: /// Constructor allocates the pointer. - new_aligned_pointer() : + new_aligned_pointer() : m_ptr(allocate_aligned(sizeof(T), internal::align_of<T>::value)) {} /// Destructor deallocates the pointer. ~new_aligned_pointer() { if (m_ptr) deallocate_aligned(m_ptr); } /// Get the pointer. operator void*() { return m_ptr; } /// Return the pointer and release the guard. - T* ok() { + T* ok() { T* ptr = static_cast<T*>(m_ptr); m_ptr = 0; return ptr; |