Stingray SDK headers taken from https://github.com/AutodeskGames/stingray-plugin/
179 lines
5.6 KiB
C++
179 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include <algorithm>
|
|
#include "allocator.h"
|
|
#include "template_tools.h"
|
|
|
|
namespace stingray_plugin_foundation {
|
|
|
|
// A replacement for std::pair that is allocator aware, so that any
|
|
// of the pair members that need to be constructed with an allocator is.
|
|
//
|
|
// The default template implementation is used when none of the types
|
|
// are allocator aware.
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
struct Pair {
|
|
typedef Pair<FIRST, SECOND, firstaware, secondaware> this_type;
|
|
typedef FIRST first_type;
|
|
typedef SECOND second_type;
|
|
|
|
Pair() : first(first_type()), second(second_type()) {}
|
|
Pair(Allocator &) : first(first_type()), second(second_type()) {}
|
|
Pair(const this_type &t) : first(t.first), second(t.second) {}
|
|
Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
|
|
|
|
void swap(this_type &right) {
|
|
std::swap(first, right.first);
|
|
std::swap(second, right.second);
|
|
}
|
|
|
|
template <class STREAM> void serialize(STREAM &s) {s & first & second;}
|
|
|
|
first_type first;
|
|
second_type second;
|
|
};
|
|
|
|
// Template specialization to use when the first type is allocator aware.
|
|
template <class FIRST, class SECOND>
|
|
struct Pair<FIRST, SECOND, true, false>
|
|
{
|
|
ALLOCATOR_AWARE;
|
|
|
|
typedef Pair<FIRST, SECOND, true, false> this_type;
|
|
typedef FIRST first_type;
|
|
typedef SECOND second_type;
|
|
|
|
Pair(Allocator &a) : first(a), second(second_type()) {}
|
|
Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
|
|
|
|
void swap(this_type &right) {
|
|
std::swap(first, right.first);
|
|
std::swap(second, right.second);
|
|
}
|
|
|
|
template <class STREAM> void serialize(STREAM &s) {s & first & second;}
|
|
|
|
first_type first;
|
|
second_type second;
|
|
};
|
|
|
|
// Template specialization to use when the second type is allocator aware.
|
|
template <class FIRST, class SECOND>
|
|
struct Pair<FIRST, SECOND, false, true>
|
|
{
|
|
ALLOCATOR_AWARE;
|
|
|
|
typedef Pair<FIRST, SECOND, false, true> this_type;
|
|
typedef FIRST first_type;
|
|
typedef SECOND second_type;
|
|
|
|
Pair(Allocator &a) : first(first_type()), second(a) {}
|
|
Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
|
|
|
|
void swap(this_type &right) {
|
|
std::swap(first, right.first);
|
|
std::swap(second, right.second);
|
|
}
|
|
|
|
template <class STREAM> void serialize(STREAM &s) {s & first & second;}
|
|
|
|
first_type first;
|
|
second_type second;
|
|
};
|
|
|
|
// Template specialization to use when both types are allocator aware.
|
|
template <class FIRST, class SECOND>
|
|
struct Pair<FIRST, SECOND, true, true>
|
|
{
|
|
ALLOCATOR_AWARE;
|
|
|
|
typedef Pair<FIRST, SECOND, true, true> this_type;
|
|
typedef FIRST first_type;
|
|
typedef SECOND second_type;
|
|
|
|
Pair(Allocator &a) : first(a), second(a) {}
|
|
Pair(const first_type &f, const second_type &s) : first(f), second(s) {}
|
|
|
|
void swap(this_type &right) {
|
|
std::swap(first, right.first);
|
|
std::swap(second, right.second);
|
|
}
|
|
|
|
template <class STREAM> void serialize(STREAM &s) {s & first & second;}
|
|
|
|
first_type first;
|
|
second_type second;
|
|
};
|
|
|
|
// Comparison operators.
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator==(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return left.first == right.first && left.second == right.second;
|
|
}
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator!=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return !(left == right);
|
|
}
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator<(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return left.first < right.first ||
|
|
(!(right.first < left.first) && left.second < right.second);
|
|
}
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator>(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return (right < left);
|
|
}
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator<=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return !(right < left);
|
|
}
|
|
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
bool operator>=(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
return !(left < right);
|
|
}
|
|
|
|
// make_pair function that constructs a Pair of the right type
|
|
template <class FIRST, class SECOND>
|
|
Pair<FIRST, SECOND, IS_ALLOCATOR_AWARE(FIRST), IS_ALLOCATOR_AWARE(SECOND)> make_pair(const FIRST &f, const SECOND &s)
|
|
{
|
|
return Pair<FIRST, SECOND, IS_ALLOCATOR_AWARE(FIRST), IS_ALLOCATOR_AWARE(SECOND)>(f, s);
|
|
}
|
|
|
|
// swap implementation for Pair
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
void swap(const Pair<FIRST,SECOND,firstaware,secondaware> &left,
|
|
const Pair<FIRST,SECOND,firstaware,secondaware> &right) {
|
|
left.swap(right);
|
|
}
|
|
|
|
// Declaration needed for GCC-based compilers
|
|
unsigned murmur_hash( const void * key, int len, unsigned seed );
|
|
|
|
// Pair hashing
|
|
template <class HASH_FIRST, class HASH_SECOND = HASH_FIRST>
|
|
struct pair_hash
|
|
{
|
|
template <class FIRST, class SECOND, bool firstaware, bool secondaware>
|
|
unsigned operator()(const Pair<FIRST, SECOND, firstaware, secondaware> &pair) const
|
|
{
|
|
HASH_FIRST hash_first;
|
|
HASH_SECOND hash_second;
|
|
const unsigned result[2] = { hash_first(pair.first), hash_second(pair.second) };
|
|
const unsigned hash = murmur_hash(&result[0], sizeof(result), 0);
|
|
return hash;
|
|
}
|
|
};
|
|
|
|
} // namespace stingray_plugin_foundation
|