2013-06-05 19:19:00 +00:00
|
|
|
#pragma once
|
|
|
|
|
#include <fc/crypto/base64.hpp>
|
|
|
|
|
#include <fc/variant.hpp>
|
2014-05-17 19:35:44 +00:00
|
|
|
#include <fc/reflect/reflect.hpp>
|
2012-09-26 03:20:25 +00:00
|
|
|
|
|
|
|
|
namespace fc {
|
|
|
|
|
|
2013-07-04 01:35:30 +00:00
|
|
|
/**
|
|
|
|
|
* Provides a fixed size array that is easier for templates to specialize
|
|
|
|
|
* against or overload than T[N].
|
|
|
|
|
*/
|
2012-09-26 03:20:25 +00:00
|
|
|
template<typename T, size_t N>
|
|
|
|
|
class array {
|
|
|
|
|
public:
|
2013-07-04 01:35:30 +00:00
|
|
|
/**
|
|
|
|
|
* 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; }
|
|
|
|
|
|
2012-09-26 03:20:25 +00:00
|
|
|
T data[N];
|
|
|
|
|
};
|
|
|
|
|
|
2013-08-02 18:32:59 +00:00
|
|
|
/** 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];
|
|
|
|
|
};
|
|
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
template<typename T, size_t N>
|
|
|
|
|
bool operator == ( const array<T,N>& a, const array<T,N>& b )
|
2013-07-07 02:07:12 +00:00
|
|
|
{ return 0 == memcmp( a.data, b.data, N*sizeof(T) ); }
|
2013-07-18 05:58:36 +00:00
|
|
|
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 ; }
|
2013-07-04 01:35:30 +00:00
|
|
|
|
2013-09-04 21:58:35 +00:00
|
|
|
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 ; }
|
|
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
template<typename T, size_t N>
|
|
|
|
|
bool operator != ( const array<T,N>& a, const array<T,N>& b )
|
2013-07-07 02:07:12 +00:00
|
|
|
{ return 0 != memcmp( a.data, b.data, N*sizeof(T) ); }
|
2012-09-26 03:20:25 +00:00
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
template<typename T, size_t N>
|
|
|
|
|
void to_variant( const array<T,N>& bi, variant& v )
|
|
|
|
|
{
|
2013-06-27 18:45:11 +00:00
|
|
|
v = std::vector<char>( (const char*)&bi, ((const char*)&bi) + sizeof(bi) );
|
2013-06-05 19:19:00 +00:00
|
|
|
}
|
|
|
|
|
template<typename T, size_t N>
|
|
|
|
|
void from_variant( const variant& v, array<T,N>& bi )
|
|
|
|
|
{
|
2013-06-27 18:45:11 +00:00
|
|
|
std::vector<char> ve = v.as< std::vector<char> >();
|
2013-06-05 19:19:00 +00:00
|
|
|
if( ve.size() )
|
|
|
|
|
{
|
|
|
|
|
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
memset( &bi, char(0), sizeof(bi) );
|
|
|
|
|
}
|
2013-07-17 19:00:13 +00:00
|
|
|
|
|
|
|
|
|
2014-05-17 19:35:44 +00:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
};
|
2013-07-17 19:00:13 +00:00
|
|
|
}
|
|
|
|
|
|
2014-02-06 08:22:09 +00:00
|
|
|
#include <unordered_map>
|
2013-07-17 19:00:13 +00:00
|
|
|
#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
|
|
|
|
|
{
|
2014-05-14 21:11:36 +00:00
|
|
|
return fc::city_hash_size_t( (char*)&e, sizeof(e) );
|
2013-07-17 19:00:13 +00:00
|
|
|
}
|
|
|
|
|
};
|
2013-06-05 19:19:00 +00:00
|
|
|
}
|
2014-05-17 19:35:44 +00:00
|
|
|
|