145 lines
4.2 KiB
C++
Executable file
145 lines
4.2 KiB
C++
Executable file
#pragma once
|
|
#include <fc/crypto/base64.hpp>
|
|
#include <fc/variant.hpp>
|
|
#include <fc/reflect/reflect.hpp>
|
|
|
|
namespace fc {
|
|
|
|
/**
|
|
* Provides a fixed size array that is easier for templates to specialize
|
|
* against or overload than T[N].
|
|
*/
|
|
template<typename T, size_t N>
|
|
class array {
|
|
public:
|
|
/**
|
|
* Checked indexing (when in debug build) that also simplifies dereferencing
|
|
* when you have an array<T,N>*.
|
|
*/
|
|
///@{
|
|
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
|
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
|
///@}
|
|
|
|
T& operator[]( size_t pos ) { assert( pos < N); return data[pos]; }
|
|
const T& operator[]( size_t pos )const { assert( pos < N); return data[pos]; }
|
|
|
|
|
|
const T* begin()const { return &data[0]; }
|
|
const T* end()const { return &data[N]; }
|
|
|
|
T* begin() { return &data[0]; }
|
|
T* end() { return &data[N]; }
|
|
|
|
size_t size()const { return N; }
|
|
|
|
T data[N];
|
|
};
|
|
|
|
/** provided for default 0 init */
|
|
template<size_t N>
|
|
class array<unsigned char,N>
|
|
{
|
|
public:
|
|
typedef unsigned char T;
|
|
array(){ memset( data, 0, sizeof(data) ); }
|
|
/**
|
|
* Checked indexing (when in debug build) that also simplifies dereferencing
|
|
* when you have an array<T,N>*.
|
|
*/
|
|
///@{
|
|
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
|
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
|
///@}
|
|
|
|
T* begin() { return &data[0]; }
|
|
const T* begin()const { return &data[0]; }
|
|
const T* end()const { return &data[N]; }
|
|
|
|
size_t size()const { return N; }
|
|
|
|
T data[N];
|
|
};
|
|
|
|
/** provided for default 0 init */
|
|
template<size_t N>
|
|
class array<char,N>
|
|
{
|
|
public:
|
|
typedef char T;
|
|
array(){ memset( data, 0, sizeof(data) ); }
|
|
/**
|
|
* Checked indexing (when in debug build) that also simplifies dereferencing
|
|
* when you have an array<T,N>*.
|
|
*/
|
|
///@{
|
|
T& at( size_t pos ) { assert( pos < N); return data[pos]; }
|
|
const T& at( size_t pos )const { assert( pos < N); return data[pos]; }
|
|
///@}
|
|
|
|
T* begin() { return &data[0]; }
|
|
const T* begin()const { return &data[0]; }
|
|
const T* end()const { return &data[N]; }
|
|
|
|
size_t size()const { return N; }
|
|
|
|
T data[N];
|
|
};
|
|
|
|
template<typename T, size_t N>
|
|
bool operator == ( const array<T,N>& a, const array<T,N>& b )
|
|
{ return 0 == memcmp( a.data, b.data, N*sizeof(T) ); }
|
|
template<typename T, size_t N>
|
|
bool operator < ( const array<T,N>& a, const array<T,N>& b )
|
|
{ return memcmp( a.data, b.data, N*sizeof(T) ) < 0 ; }
|
|
|
|
template<typename T, size_t N>
|
|
bool operator > ( const array<T,N>& a, const array<T,N>& b )
|
|
{ return memcmp( a.data, b.data, N*sizeof(T) ) > 0 ; }
|
|
|
|
template<typename T, size_t N>
|
|
bool operator != ( const array<T,N>& a, const array<T,N>& b )
|
|
{ return 0 != memcmp( a.data, b.data, N*sizeof(T) ); }
|
|
|
|
template<typename T, size_t N>
|
|
void to_variant( const array<T,N>& bi, variant& v, uint32_t max_depth = 1 )
|
|
{
|
|
to_variant( std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) ), v, 1 );
|
|
}
|
|
template<typename T, size_t N>
|
|
void from_variant( const variant& v, array<T,N>& bi, uint32_t max_depth = 1 )
|
|
{
|
|
std::vector<char> ve = v.as< std::vector<char> >( 1 );
|
|
if( ve.size() )
|
|
{
|
|
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
|
}
|
|
else
|
|
memset( &bi, char(0), sizeof(bi) );
|
|
}
|
|
|
|
|
|
template<typename T,size_t N> struct get_typename< fc::array<T,N> >
|
|
{
|
|
static const char* name()
|
|
{
|
|
static std::string _name = std::string("fc::array<")+std::string(fc::get_typename<T>::name())+","+ fc::to_string(N) + ">";
|
|
return _name.c_str();
|
|
}
|
|
};
|
|
}
|
|
|
|
#include <unordered_map>
|
|
#include <fc/crypto/city.hpp>
|
|
namespace std
|
|
{
|
|
template<typename T, size_t N>
|
|
struct hash<fc::array<T,N> >
|
|
{
|
|
size_t operator()( const fc::array<T,N>& e )const
|
|
{
|
|
return fc::city_hash_size_t( (char*)&e, sizeof(e) );
|
|
}
|
|
};
|
|
}
|
|
|