]> git.ipfire.org Git - thirdparty/gcc.git/blame - libcilkrts/include/cilk/metaprogramming.h
[Patch AArch64] Fixup floating point division with -march=armv8-a+nosimd
[thirdparty/gcc.git] / libcilkrts / include / cilk / metaprogramming.h
CommitLineData
3038054c
BI
1/* metaprogramming.h -*- C++ -*-
2 *
2e01cda6 3 * Copyright (C) 2012-2016, Intel Corporation
3038054c
BI
4 * All rights reserved.
5 *
3038054c
BI
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Intel Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
3038054c
BI
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
30 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
2e01cda6
IV
32 *
33 * *********************************************************************
34 *
35 * PLEASE NOTE: This file is a downstream copy of a file mainitained in
36 * a repository at cilkplus.org. Changes made to this file that are not
37 * submitted through the contribution process detailed at
38 * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
39 * time that a new version is released. Changes only submitted to the
40 * GNU compiler collection or posted to the git repository at
41 * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
42 * not tracked.
43 *
44 * We welcome your contributions to this open source project. Thank you
45 * for your assistance in helping us improve Cilk Plus.
3038054c
BI
46 */
47
48/** @file metaprogramming.h
49 *
2e01cda6 50 * @brief Defines metaprogramming utility classes used in the Intel(R) Cilk(TM) Plus library.
3038054c
BI
51 *
52 * @ingroup common
53 */
54
55#ifndef METAPROGRAMMING_H_INCLUDED
56#define METAPROGRAMMING_H_INCLUDED
57
58#ifdef __cplusplus
59
60#include <functional>
61#include <new>
62#include <cstdlib>
63#ifdef _WIN32
64#include <malloc.h>
65#endif
66#include <algorithm>
67
68namespace cilk {
69
70namespace internal {
71
72/** Test if a class is empty.
73 *
74 * If @a Class is an empty (and therefore necessarily stateless) class, then
2e01cda6 75 * the "empty base-class optimization" guarantees that
3038054c
BI
76 * `sizeof(check_for_empty_class<Class>) == sizeof(char)`. Conversely, if
77 * `sizeof(check_for_empty_class<Class>) > sizeof(char)`, then @a Class is not
78 * empty, and we must discriminate distinct instances of @a Class.
79 *
80 * Typical usage:
81 *
82 * // General definition of A<B> for non-empty B:
83 * template <typename B, bool BIsEmpty = class_is_empty<B>::value> >
84 * class A { ... };
85 *
86 * // Specialized definition of A<B> for empty B:
87 * template <typename B>
88 * class A<B, true> { ... };
89 *
90 * @tparam Class The class to be tested for emptiness.
91 *
92 * @result The `value` member will be `true` if @a Class is empty,
93 * `false` otherwise.
94 *
95 * @ingroup common
96 */
97template <class Class>
2e01cda6 98class class_is_empty {
3038054c
BI
99 class check_for_empty_class : public Class
100 {
101 char m_data;
102 public:
103 // Declared but not defined
104 check_for_empty_class();
105 check_for_empty_class(const check_for_empty_class&);
106 check_for_empty_class& operator=(const check_for_empty_class&);
107 ~check_for_empty_class();
108 };
109public:
110
111 /** Constant is true if and only if @a Class is empty.
112 */
113 static const bool value = (sizeof(check_for_empty_class) == sizeof(char));
114};
115
116
117/** Get the alignment of a type.
118 *
119 * For example:
120 *
121 * align_of<double>::value == 8
122 *
123 * @tparam Tp The type whose alignment is to be computed.
124 *
125 * @result The `value` member of an instantiation of this class template
126 * will hold the integral alignment requirement of @a Tp.
127 *
128 * @pre @a Tp shall be a complete type.
129 *
130 * @ingroup common
131 */
132template <typename Tp>
133struct align_of
134{
135private:
136 struct imp {
137 char m_padding;
138 Tp m_val;
139
140 // The following declarations exist to suppress compiler-generated
141 // definitions, in case @a Tp does not have a public default
142 // constructor, copy constructor, or destructor.
143 imp(const imp&); // Declared but not defined
144 ~imp(); // Declared but not defined
145 };
146
147public:
148 /// The integral alignment requirement of @a Tp.
149 static const std::size_t value = (sizeof(imp) - sizeof(Tp));
150};
151
152
153/** A class containing raw bytes with a specified alignment and size.
154 *
155 * An object of type `aligned_storage<S, A>` will have alignment `A` and
156 * size at least `S`. Its contents will be uninitialized bytes.
157 *
158 * @tparam Size The required minimum size of the resulting class.
159 * @tparam Alignment The required alignment of the resulting class.
160 *
2e01cda6 161 * @pre @a Alignment shall be a power of 2 no greater than 64.
3038054c
BI
162 *
163 * @note This is implemented using the `CILK_ALIGNAS` macro, which uses
164 * the non-standard, implementation-specific features
2e01cda6 165 * `__declspec(align(N))` on Windows, and
3038054c
BI
166 * `__attribute__((__aligned__(N)))` on Unix. The `gcc` implementation
167 * of `__attribute__((__aligned__(N)))` requires a numeric literal `N`
168 * (_not_ an arbitrary compile-time constant expression). Therefore,
169 * this class is implemented using specialization on the required
170 * alignment.
171 *
172 * @note The template class is specialized only for the supported
173 * alignments. An attempt to instantiate it for an unsupported
174 * alignment will result in a compilation error.
175 */
176template <std::size_t Size, std::size_t Alignment>
177struct aligned_storage;
178
2e01cda6
IV
179/// @cond
180template<std::size_t Size> class aligned_storage<Size, 1>
3038054c 181 { CILK_ALIGNAS( 1) char m_bytes[Size]; };
2e01cda6 182template<std::size_t Size> class aligned_storage<Size, 2>
3038054c 183 { CILK_ALIGNAS( 2) char m_bytes[Size]; };
2e01cda6 184template<std::size_t Size> class aligned_storage<Size, 4>
3038054c 185 { CILK_ALIGNAS( 4) char m_bytes[Size]; };
2e01cda6 186template<std::size_t Size> class aligned_storage<Size, 8>
3038054c 187 { CILK_ALIGNAS( 8) char m_bytes[Size]; };
2e01cda6 188template<std::size_t Size> class aligned_storage<Size, 16>
3038054c 189 { CILK_ALIGNAS(16) char m_bytes[Size]; };
2e01cda6 190template<std::size_t Size> class aligned_storage<Size, 32>
3038054c 191 { CILK_ALIGNAS(32) char m_bytes[Size]; };
2e01cda6 192template<std::size_t Size> class aligned_storage<Size, 64>
3038054c 193 { CILK_ALIGNAS(64) char m_bytes[Size]; };
2e01cda6 194/// @endcond
3038054c
BI
195
196/** A buffer of uninitialized bytes with the same size and alignment as a
197 * specified type.
198 *
199 * The class `storage_for_object<Type>` will have the same size and alignment
200 * properties as `Type`, but it will contain only raw (uninitialized) bytes.
201 * This allows the definition of a data member which can contain a `Type`
202 * object which is initialized explicitly under program control, rather
2e01cda6 203 * than implicitly as part of the initialization of the containing class.
3038054c
BI
204 * For example:
205 *
206 * class C {
207 * storage_for_object<MemberClass> _member;
208 * public:
209 * C() ... // Does NOT initialize _member
2e01cda6 210 * void initialize(args)
3038054c
BI
211 * { new (_member.pointer()) MemberClass(args); }
212 * const MemberClass& member() const { return _member.object(); }
213 * MemberClass& member() { return _member.object(); }
214 *
215 * @tparam Type The type whose size and alignment are to be reflected
216 * by this class.
217 */
218template <typename Type>
2e01cda6 219class storage_for_object :
3038054c
BI
220 aligned_storage< sizeof(Type), align_of<Type>::value >
221{
222public:
223 /// Return a typed reference to the buffer.
224 const Type& object() const { return *reinterpret_cast<Type*>(this); }
2e01cda6 225 /// Return a typed reference to the buffer.
3038054c
BI
226 Type& object() { return *reinterpret_cast<Type*>(this); }
227};
228
229
230/** Get the functor class corresponding to a binary function type.
231 *
2e01cda6 232 * The `binary_functor` template class can be instantiated with a binary
3038054c 233 * functor class or with a real binary function, and will yield an equivalent
2e01cda6 234 * binary functor class in either case.
3038054c
BI
235 *
236 * @tparam F A binary functor class, a binary function type, or a pointer to
237 * binary function type.
238 *
239 * @result `binary_functor<F>::%type` will be the same as @a F if @a F is
240 * a class. It will be a `std::pointer_to_binary_function` wrapper
241 * if @a F is a binary function or binary function pointer type.
242 * (It will _not_ necessarily be an `Adaptable Binary Function`
243 * class, since @a F might be a non-adaptable binary functor
244 * class.)
245 *
246 * @ingroup common
247 */
248template <typename F>
249struct binary_functor {
250 /// The binary functor class equivalent to @a F.
251 typedef F type;
252};
253
254/// @copydoc binary_functor
255/// Specialization for binary function.
256template <typename R, typename A, typename B>
257struct binary_functor<R(A,B)> {
258 /// The binary functor class equivalent to @a F.
259 typedef std::pointer_to_binary_function<A, B, R> type;
260};
261
262/// @copydoc binary_functor
263/// Specialization for pointer to binary function.
264template <typename R, typename A, typename B>
265struct binary_functor<R(*)(A,B)> {
266 /// The binary functor class equivalent to @a F.
267 typedef std::pointer_to_binary_function<A, B, R> type;
268};
269
270
271/** Indirect binary function class with specified types.
272 *
273 * `typed_indirect_binary_function<F>` is an `Adaptable Binary Function` class
274 * based on an existing binary functor class or binary function type @a F. If
275 * @a F is a stateless class, then this class will be empty, and its
2e01cda6 276 * `operator()` will invoke @a F's `operator()`. Otherwise, an object of this
3038054c
BI
277 * class will hold a pointer to an object of type @a F, and will refer its
278 * `operator()` calls to the pointed-to @a F object.
279 *
280 * That is, suppose that we have the declarations:
281 *
282 * F *p;
283 * typed_indirect_binary_function<F, int, int, bool> ibf(p);
284 *
285 * Then:
286 *
287 * - `ibf(x, y) == (*p)(x, y)`.
288 * - `ibf(x, y)` will not do a pointer dereference if `F` is an empty class.
289 *
290 * @note Just to repeat: if `F` is an empty class, then
291 * `typed_indirect_binary_function\<F\>' is also an empty class.
2e01cda6
IV
292 * This is critical for its use in the
293 * @ref cilk::cilk_lib_1_1::min_max_internal::view_base
3038054c
BI
294 * "min/max reducer view classes", where it allows the view to
295 * call a comparison functor in the monoid without actually
2e01cda6 296 * having to allocate a pointer in the view class when the
3038054c
BI
297 * comparison class is empty.
298 *
299 * @note If you have an `Adaptable Binary Function` class or a binary
2e01cda6 300 * function type, then you can use the
3038054c
BI
301 * @ref indirect_binary_function class, which derives the
302 * argument and result types parameter type instead of requiring
303 * you to specify them as template arguments.
304 *
305 * @tparam F A binary functor class, a binary function type, or a pointer to
306 * binary function type.
307 * @param A1 The first argument type.
308 * @param A2 The second argument type.
309 * @param R The result type.
310 *
311 * @see min_max::comparator_base
312 * @see indirect_binary_function
313 *
314 * @ingroup common
315 */
316template < typename F
317 , typename A1
318 , typename A2
319 , typename R
320 , typename Functor = typename binary_functor<F>::type
321 , bool FunctorIsEmpty = class_is_empty<Functor>::value
322 >
323class typed_indirect_binary_function : std::binary_function<A1, A2, R>
324{
325 const F* f;
326public:
327 /// Constructor captures a pointer to the wrapped function.
328 typed_indirect_binary_function(const F* f) : f(f) {}
2e01cda6 329
3038054c
BI
330 /// Return the comparator pointer, or `NULL` if the comparator is stateless.
331 const F* pointer() const { return f; }
332
333 /// Apply the pointed-to functor to the arguments.
334 R operator()(const A1& a1, const A2& a2) const { return (*f)(a1, a2); }
335};
336
337
338/// @copydoc typed_indirect_binary_function
339/// Specialization for an empty functor class. (This is only possible if @a F
2e01cda6 340/// itself is an empty class. If @a F is a function or pointer-to-function
3038054c
BI
341/// type, then the functor will contain a pointer.)
342template <typename F, typename A1, typename A2, typename R, typename Functor>
2e01cda6 343class typed_indirect_binary_function<F, A1, A2, R, Functor, true> :
3038054c
BI
344 std::binary_function<A1, A2, R>
345{
346public:
347 /// Return `NULL` for the comparator pointer of a stateless comparator.
348 const F* pointer() const { return 0; }
349
350 /// Constructor discards the pointer to a stateless functor class.
351 typed_indirect_binary_function(const F* f) {}
2e01cda6 352
3038054c
BI
353 /// Create an instance of the stateless functor class and apply it to the arguments.
354 R operator()(const A1& a1, const A2& a2) const { return F()(a1, a2); }
355};
356
357
358/** Indirect binary function class with inferred types.
359 *
2e01cda6
IV
360 * This is identical to @ref cilk::internal::typed_indirect_binary_function,
361 * except that it derives the binary function argument and result types from
362 * the parameter type @a F instead of taking them as additional template
363 * parameters. If @a F is a class type, then it must be an `Adaptable Binary
364 * Function`.
3038054c
BI
365 *
366 * @see typed_indirect_binary_function
367 *
368 * @ingroup common
369 */
370template <typename F, typename Functor = typename binary_functor<F>::type>
2e01cda6 371class indirect_binary_function :
3038054c
BI
372 typed_indirect_binary_function< F
373 , typename Functor::first_argument_type
374 , typename Functor::second_argument_type
375 , typename Functor::result_type
2e01cda6 376 >
3038054c
BI
377{
378 typedef typed_indirect_binary_function< F
379 , typename Functor::first_argument_type
380 , typename Functor::second_argument_type
381 , typename Functor::result_type
2e01cda6 382 >
3038054c
BI
383 base;
384public:
385 indirect_binary_function(const F* f) : base(f) {} ///< Constructor
386};
387
388
389/** Choose a type based on a boolean constant.
390 *
2e01cda6 391 * This metafunction is identical to C++11's condition metafunction.
3038054c
BI
392 * It needs to be here until we can reasonably assume that users will be
393 * compiling with C++11.
394 *
395 * @tparam Cond A boolean constant.
396 * @tparam IfTrue A type.
397 * @tparam IfFalse A type.
398 * @result The `type` member will be a typedef of @a IfTrue if @a Cond
399 * is true, and a typedef of @a IfFalse if @a Cond is false.
400 *
401 * @ingroup common
402 */
403template <bool Cond, typename IfTrue, typename IfFalse>
404struct condition
405{
406 typedef IfTrue type; ///< The type selected by the condition.
407};
408
409/// @copydoc condition
410/// Specialization for @a Cond == `false`.
411template <typename IfTrue, typename IfFalse>
412struct condition<false, IfTrue, IfFalse>
413{
414 typedef IfFalse type; ///< The type selected by the condition.
415};
416
417
418/** @def __CILKRTS_STATIC_ASSERT
419 *
420 * @brief Compile-time assertion.
421 *
422 * Causes a compilation error if a compile-time constant expression is false.
423 *
424 * @par Usage example.
2e01cda6 425 * This assertion is used in reducer_min_max.h to avoid defining
3038054c
BI
426 * legacy reducer classes that would not be binary-compatible with the
427 * same classes compiled with earlier versions of the reducer library.
428 *
429 * __CILKRTS_STATIC_ASSERT(
2e01cda6 430 * internal::class_is_empty< internal::binary_functor<Compare> >::value,
3038054c
BI
431 * "cilk::reducer_max<Value, Compare> only works with an empty Compare class");
432 *
433 * @note In a C++11 compiler, this is just the language predefined
434 * `static_assert` macro.
435 *
436 * @note In a non-C++11 compiler, the @a Msg string is not directly included
437 * in the compiler error message, but it may appear if the compiler
438 * prints the source line that the error occurred on.
439 *
440 * @param Cond The expression to test.
441 * @param Msg A string explaining the failure.
442 *
443 * @ingroup common
444 */
445#if defined(__INTEL_CXX11_MODE__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
446# define __CILKRTS_STATIC_ASSERT(Cond, Msg) static_assert(Cond, Msg)
447#else
448# define __CILKRTS_STATIC_ASSERT(Cond, Msg) \
449 typedef int __CILKRTS_STATIC_ASSERT_DUMMY_TYPE \
450 [::cilk::internal::static_assert_failure<(Cond)>::Success]
451
452/// @cond internal
453 template <bool> struct static_assert_failure { };
454 template <> struct static_assert_failure<true> { enum { Success = 1 }; };
455
456# define __CILKRTS_STATIC_ASSERT_DUMMY_TYPE \
457 __CILKRTS_STATIC_ASSERT_DUMMY_TYPE1(__cilkrts_static_assert_, __LINE__)
458# define __CILKRTS_STATIC_ASSERT_DUMMY_TYPE1(a, b) \
459 __CILKRTS_STATIC_ASSERT_DUMMY_TYPE2(a, b)
460# define __CILKRTS_STATIC_ASSERT_DUMMY_TYPE2(a, b) a ## b
461/// @endcond
462
463#endif
464
465/// @cond internal
466
467/** @name Aligned heap management.
468 */
469//@{
470
471/** Implementation-specific aligned memory allocation function.
472 *
473 * @param size The minimum number of bytes to allocate.
474 * @param alignment The required alignment (must be a power of 2).
475 * @return The address of a block of memory of at least @a size
476 * bytes. The address will be a multiple of @a alignment.
477 * `NULL` if the allocation fails.
478 *
479 * @see deallocate_aligned()
480 */
481inline void* allocate_aligned(std::size_t size, std::size_t alignment)
482{
483#ifdef _WIN32
484 return _aligned_malloc(size, alignment);
485#else
2e01cda6 486#if defined(__ANDROID__) || defined(__VXWORKS__)
3038054c
BI
487 return memalign(std::max(alignment, sizeof(void*)), size);
488#else
489 void* ptr;
490 return (posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0) ? ptr : 0;
491#endif
2e01cda6 492#endif
3038054c
BI
493}
494
495/** Implementation-specific aligned memory deallocation function.
496 *
497 * @param ptr A pointer which was returned by a call to alloc_aligned().
498 */
499inline void deallocate_aligned(void* ptr)
500{
501#ifdef _WIN32
502 _aligned_free(ptr);
503#else
504 std::free(ptr);
2e01cda6 505#endif
3038054c
BI
506}
507
508/** Class to allocate and guard an aligned pointer.
509 *
510 * A new_aligned_pointer object allocates aligned heap-allocated memory when
2e01cda6 511 * it is created, and automatically deallocates it when it is destroyed
3038054c
BI
512 * unless its `ok()` function is called.
513 *
514 * @tparam T The type of the object to allocate on the heap. The allocated
515 * will have the size and alignment of an object of type T.
516 */
517template <typename T>
518class new_aligned_pointer {
519 void* m_ptr;
520public:
521 /// Constructor allocates the pointer.
2e01cda6 522 new_aligned_pointer() :
3038054c
BI
523 m_ptr(allocate_aligned(sizeof(T), internal::align_of<T>::value)) {}
524 /// Destructor deallocates the pointer.
525 ~new_aligned_pointer() { if (m_ptr) deallocate_aligned(m_ptr); }
526 /// Get the pointer.
527 operator void*() { return m_ptr; }
528 /// Return the pointer and release the guard.
2e01cda6 529 T* ok() {
3038054c
BI
530 T* ptr = static_cast<T*>(m_ptr);
531 m_ptr = 0;
532 return ptr;
533 }
534};
535
536//@}
537
538/// @endcond
539
540} // namespace internal
541
542//@{
543
544/** Allocate an aligned data structure on the heap.
545 *
546 * `cilk::aligned_new<T>([args])` is equivalent to `new T([args])`, except
547 * that it guarantees that the returned pointer will be at least as aligned
548 * as the alignment requirements of type `T`.
549 *
550 * @ingroup common
551 */
552template <typename T>
553T* aligned_new()
554{
555 internal::new_aligned_pointer<T> ptr;
556 new (ptr) T();
557 return ptr.ok();
558}
559
560template <typename T, typename T1>
561T* aligned_new(const T1& x1)
562{
563 internal::new_aligned_pointer<T> ptr;
564 new (ptr) T(x1);
565 return ptr.ok();
566}
567
568template <typename T, typename T1, typename T2>
569T* aligned_new(const T1& x1, const T2& x2)
570{
571 internal::new_aligned_pointer<T> ptr;
572 new (ptr) T(x1, x2);
573 return ptr.ok();
574}
575
576template <typename T, typename T1, typename T2, typename T3>
577T* aligned_new(const T1& x1, const T2& x2, const T3& x3)
578{
579 internal::new_aligned_pointer<T> ptr;
580 new (ptr) T(x1, x2, x3);
581 return ptr.ok();
582}
583
584template <typename T, typename T1, typename T2, typename T3, typename T4>
585T* aligned_new(const T1& x1, const T2& x2, const T3& x3, const T4& x4)
586{
587 internal::new_aligned_pointer<T> ptr;
588 new (ptr) T(x1, x2, x3, x4);
589 return ptr.ok();
590}
591
592template <typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
593T* aligned_new(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5)
594{
595 internal::new_aligned_pointer<T> ptr;
596 new (ptr) T(x1, x2, x3, x4, x5);
597 return ptr.ok();
598}
599
600//@}
601
602
603/** Deallocate an aligned data structure on the heap.
604 *
605 * `cilk::aligned_delete(ptr)` is equivalent to `delete ptr`, except that it
606 * operates on a pointer that was allocated by aligned_new().
607 *
608 * @ingroup common
609 */
610template <typename T>
611void aligned_delete(const T* ptr)
612{
613 ptr->~T();
614 internal::deallocate_aligned((void*)ptr);
615}
616
617} // namespace cilk
618
619#endif // __cplusplus
620
621#endif // METAPROGRAMMING_H_INCLUDED