28#ifndef VC_COMMON_LOADSTOREFLAGS_H_
29#define VC_COMMON_LOADSTOREFLAGS_H_
31#include "../traits/type_traits.h"
33namespace Vc_VERSIONED_NAMESPACE
47namespace LoadStoreFlags
50struct StreamingFlag {};
51struct UnalignedFlag {};
52struct PrefetchFlagBase {};
54template <
size_t L1 = 16 * 64,
size_t L2 = 128 * 64,
typename ExclusiveOrShared_ =
void>
55struct PrefetchFlag :
public PrefetchFlagBase {
56 typedef ExclusiveOrShared_ ExclusiveOrShared;
57 static constexpr size_t L1Stride = L1;
58 static constexpr size_t L2Stride = L2;
59 static constexpr bool IsExclusive = std::is_same<ExclusiveOrShared, Exclusive>::value;
60 static constexpr bool IsShared = std::is_same<ExclusiveOrShared, Shared>::value;
63template<
typename Base,
typename Default,
typename... LoadStoreFlags>
struct ExtractType
67template<
typename Base,
typename Default,
typename T,
typename... LoadStoreFlags>
struct ExtractType<Base, Default, T, LoadStoreFlags...>
69 typedef typename std::conditional<std::is_base_of<Base, T>::value, T,
typename ExtractType<Base, Default, LoadStoreFlags...>::type>::type type;
77#pragma warning(disable: 177)
83template<
typename... Flags>
struct LoadStoreFlags
88 typedef typename ExtractType<PrefetchFlagBase, PrefetchFlag<0, 0>, Flags...>::type Prefetch;
91 constexpr LoadStoreFlags() {}
93 static constexpr bool IsStreaming = !std::is_same<
typename ExtractType<StreamingFlag, void, Flags...>::type,
void>::value;
94 static constexpr bool IsUnaligned = !std::is_same<
typename ExtractType<UnalignedFlag, void, Flags...>::type,
void>::value;
95 static constexpr bool IsAligned = !IsUnaligned;
96 static constexpr bool IsPrefetch = !std::is_same<
typename ExtractType<PrefetchFlagBase, void, Flags...>::type,
void>::value;
97 static constexpr bool IsExclusivePrefetch = Prefetch::IsExclusive;
98 static constexpr bool IsSharedPrefetch = Prefetch::IsShared;
99 static constexpr size_t L1Stride = Prefetch::L1Stride;
100 static constexpr size_t L2Stride = Prefetch::L2Stride;
102 typedef LoadStoreFlags<typename std::conditional<std::is_same<Flags, UnalignedFlag>::value, void, Flags>::type...> UnalignedRemoved;
108 typedef typename std::conditional<IsAligned && !IsStreaming, void *, void>::type EnableIfAligned;
109 typedef typename std::conditional<IsAligned && IsStreaming, void *, void>::type EnableIfStreaming;
110 typedef typename std::conditional<IsUnaligned && !IsStreaming, void *, void>::type EnableIfUnalignedNotStreaming;
111 typedef typename std::conditional<IsUnaligned && IsStreaming, void *, void>::type EnableIfUnalignedAndStreaming;
112 typedef typename std::conditional<IsUnaligned , void *, void>::type EnableIfUnaligned;
113 typedef typename std::conditional<!IsUnaligned , void *, void>::type EnableIfNotUnaligned;
114 typedef typename std::conditional<IsPrefetch , void *, void>::type EnableIfPrefetch;
115 typedef typename std::conditional<!IsPrefetch , void *, void>::type EnableIfNotPrefetch;
121template<>
struct LoadStoreFlags<>
123 constexpr LoadStoreFlags() {}
125 static constexpr bool IsStreaming =
false;
126 static constexpr bool IsUnaligned =
false;
127 static constexpr bool IsAligned = !IsUnaligned;
128 static constexpr bool IsPrefetch =
false;
129 static constexpr bool IsExclusivePrefetch =
false;
130 static constexpr bool IsSharedPrefetch =
false;
131 static constexpr size_t L1Stride = 0;
132 static constexpr size_t L2Stride = 0;
133 typedef void* EnableIfAligned;
134 typedef void* EnableIfNotUnaligned;
135 typedef void* EnableIfNotPrefetch;
146template<
typename... LFlags,
typename... RFlags>
147constexpr LoadStoreFlags<LFlags..., RFlags...> operator|(LoadStoreFlags<LFlags...>, LoadStoreFlags<RFlags...>)
149 return LoadStoreFlags<LFlags..., RFlags...>();
154using LoadStoreFlags::PrefetchFlag;
156typedef LoadStoreFlags::LoadStoreFlags<> AlignedTag;
157typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::StreamingFlag> StreamingTag;
158typedef LoadStoreFlags::LoadStoreFlags<LoadStoreFlags::UnalignedFlag> UnalignedTag;
161typedef UnalignedTag DefaultLoadTag;
163typedef UnalignedTag DefaultStoreTag;
220template <size_t L1 = PrefetchFlag<>::L1Stride,
221 size_t L2 = PrefetchFlag<>::L2Stride,
222 typename ExclusiveOrShared = PrefetchFlag<>::ExclusiveOrShared>
223struct Prefetch :
public LoadStoreFlags::LoadStoreFlags<PrefetchFlag<L1, L2, ExclusiveOrShared>>
230template <
typename... Ts>
231struct is_loadstoreflag_internal<LoadStoreFlags::LoadStoreFlags<Ts...>> :
public std::true_type
236template <
size_t L1,
size_t L2,
typename ExclusiveOrShared>
237struct is_loadstoreflag_internal<Prefetch<L1, L2, ExclusiveOrShared>> :
public std::true_type
constexpr LoadStoreFlags::LoadStoreFlags< PrefetchFlag<> > PrefetchDefault
Use this object for a flags parameter to request default software prefetches to be emitted.
constexpr UnalignedTag Unaligned
Use this object for a flags parameter to request unaligned loads and stores.
constexpr AlignedTag Aligned
Use this object for a flags parameter to request aligned loads and stores.
constexpr StreamingTag Streaming
Use this object for a flags parameter to request streaming loads and stores.
Hint for Prefetch to select prefetches that mark the memory as exclusive.
Hint for Prefetch to select prefetches that mark the memory as shared.