#ifndef EMPATHY_UTIL_H
#define EMPATHY_UTIL_H
#include <memory>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <iostream>
#include <sstream>
#include <fstream>
#include <queue>
#include <stack>
#include <functional>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <optional>
#include <variant>
#include <any>
#include <cassert>
#include <experimental/coroutine>
#include <immer/vector.hpp>
#include <immer/vector_transient.hpp>
#include <immer/flex_vector.hpp>
#include <immer/flex_vector_transient.hpp>
#include <immer/map.hpp>
// Provide our own specialization of std::hash for pairs,
// since it's not in the standard yet... (based on
// boost's hash_combine)
namespace std
{
template< typename A, typename B > struct hash< pair< A, B > >
{
template< typename P > size_t operator()( P&& x ) const
{
size_t result = hash< A >()( x.first );
result ^= hash< B >()( x.second ) + 0x9e3779b9
+ ( result << 6 ) + ( result >> 2 );
return result;
}
};
}
namespace empathy
{
using namespace std;
using namespace std::experimental;
}
#include "generator.h"
#include "crc32.h"
#include "stringid.h"
#include "graphviz.h"
namespace empathy::util
{
template< typename T >
using ptr = shared_ptr< T >;
template< typename T >
using remove_constref_t = remove_cv_t< remove_reference_t< T > >;
template< typename T >
struct remove_sptr
{
using type = T;
};
template< typename T >
struct remove_sptr< ptr< T > >
{
using type = T;
};
template< typename T >
using remove_sptr_t = typename remove_sptr< T >::type;
// moo
template< typename T >
static auto& CoW( ptr< T >& ptr )
{
if( ptr.use_count() > 1 )
ptr = make_shared< T >( *ptr );
return ptr;
}
template< typename T >
struct is_optional : public false_type
{};
template< typename T >
struct is_optional< optional< T > > : public true_type
{};
template< typename T >
constexpr bool is_optional_v = is_optional< T >::value;
}
#endif