Skip to content

Commit

Permalink
Added tuple interface to json_value_iterator_pair
Browse files Browse the repository at this point in the history
  • Loading branch information
beached committed Aug 28, 2020
1 parent 50cfd44 commit 7afd49a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 16 deletions.
52 changes: 52 additions & 0 deletions include/daw/json/impl/daw_json_value.h
Expand Up @@ -11,6 +11,8 @@
#include "daw_arrow_proxy.h"
#include "daw_json_parse_name.h"

#include <tuple>

namespace daw::json {
template<typename Range>
class basic_json_value;
Expand All @@ -25,6 +27,56 @@ namespace daw::json {
basic_json_value<Range> value;
};

template<std::size_t Idx, typename Range>
constexpr decltype( auto ) get( basic_json_pair<Range> const & rng ) {
static_assert( Idx < 2 );
if constexpr( Idx == 0 ) {
return rng.name;
} else {
return rng.value;
}
}

template<std::size_t Idx, typename Range>
constexpr decltype( auto ) get( basic_json_pair<Range> & rng ) {
static_assert( Idx < 2 );
if constexpr( Idx == 0 ) {
return rng.name;
} else {
return rng.value;
}
}

template<std::size_t Idx, typename Range>
constexpr decltype( auto ) get( basic_json_pair<Range> && rng ) {
static_assert( Idx < 2 );
if constexpr( Idx == 0 ) {
return std::move( rng.name );
} else {
return std::move( rng.value );
}
}
} // namespace daw::json

namespace std {
template<typename Range>
class tuple_element<0, daw::json::basic_json_pair<Range>> {
public:
using type = std::optional<std::string_view>;
};

template<typename Range>
class tuple_element<1, daw::json::basic_json_pair<Range>> {
public:
using type = daw::json::basic_json_value<Range>;
};

template<typename Range>
class std::tuple_size<daw::json::basic_json_pair<Range>>
: public std::integral_constant<std::size_t, 2> {};
} // namespace std

namespace daw::json {
/***
* Iterator for iterating over arbutrary JSON members and array elements
* @tparam Range see IteratorRange
Expand Down
27 changes: 15 additions & 12 deletions include/daw/json/impl/daw_murmur3.h
Expand Up @@ -24,39 +24,42 @@ namespace daw {
return result;
}

static inline constexpr uint32_t rotl( std::uint32_t n, unsigned c ) {
constexpr unsigned mask = ( CHAR_BIT * sizeof( n ) - 1 );
c &= mask;
return ( n << c ) | ( n >> ( ( -c ) & mask ) );
template<unsigned r>
DAW_ATTRIBUTE_FLATTEN [[nodiscard]] static inline constexpr uint32_t
rotl( std::uint32_t n ) {
return ( n << r ) | ( n >> r );
}

inline constexpr std::uint32_t
[[nodiscard]] inline constexpr std::uint32_t
murmur3_32_scramble( std::uint32_t k ) noexcept {
k *= 0xcc9e'2d51ULL;
rotl( k, 15 );
k = rotl<15>( k );
k *= 0x1b87'3593ULL;
return k;
}
} // namespace murmur3_details

template<typename String>
constexpr std::uint32_t murmur3_32( String const &key ) noexcept {
std::uint32_t h = 0; // seed
auto const len = static_cast<uint32_t>( key.size( ) );
[[nodiscard]] constexpr std::uint32_t
murmur3_32( String const &key, std::uint32_t seed = 0 ) noexcept {

std::uint32_t h = seed;
std::uint32_t const len = static_cast<uint32_t>( key.size( ) );
char const *first = key.data( );
char const *const last = key.data( ) + len;
std::uint32_t k = 0U;
while( ( last - first ) >= 4U ) {
// Here is a source of differing results across endiannesses.
// A swap here has no effects on hash properties though.
std::uint32_t k = murmur3_details::to_u32( first );
k = murmur3_details::to_u32( first );
h ^= murmur3_details::murmur3_32_scramble( k );
h = murmur3_details::rotl( h, 13 );
h = murmur3_details::rotl<13>( h );
h = h * 5U + 0xe654'6b64ULL;
first += 4;
}

// Anything left over
std::uint32_t k = 0U;
k = 0;
for( auto d = ( last - first ); d > 0; --d ) {
k <<= 8U;
char const c = *( first + ( d - 1 ) );
Expand Down
5 changes: 3 additions & 2 deletions tests/canada_test_basic.cpp
Expand Up @@ -27,8 +27,9 @@ int main( int argc, char **argv ) try {
auto json_data =
std::string( daw::filesystem::memory_mapped_file_t<>( argv[1] ) );

auto const canada_result =
daw::json::from_json<daw::geojson::FeatureCollection>( json_data );
auto const canada_result = daw::json::from_json<
daw::geojson::FeatureCollection,
daw::json::SIMDNoCommentSkippingPolicyChecked<simd_exec_tag>>( json_data );
daw::do_not_optimize( canada_result );

auto new_json_result = std::string( );
Expand Down
6 changes: 4 additions & 2 deletions tests/daw_murmur3_test.cpp
Expand Up @@ -24,8 +24,10 @@ int main( int, char ** ) {
daw::expecting( t0_b == 0x04030201 );
test( "", 0, 0 );
test( "", 1, 0x514E'28B7ULL );
test( "", 0xFFFF'FFFF, 0x81F1'6F39ULL );
test( "\xFF\xFF\xFF\xFF", 0, 0x7629'3B50ULL );
test( "", 0xFFFF'FFFF, 0x81F1'6F39ULL ); // make sure your seed uses unsigned 32-bit math
test( "\xFF\xFF\xFF\xFF", 0, 0x7629'3B50ULL ); // make sure 4-byte chunks use unsigned math
test( "\x21\x43\x65\x87", 0, 0xF55B'516BULL );
test( "\x21\x43\x65\x87", 0x5082'EDEE, 0x2362'F9DE );

test( "aaaa", 0x9747b28c, 0x5A97808A ); // one full chunk
test( "aaa", 0x9747b28c, 0x283E0130 ); // three characters
Expand Down

0 comments on commit 7afd49a

Please sign in to comment.