1// platform.h
2//
3// Copyright 2015-2018 J. Andrew Rogers
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef METROHASH_PLATFORM_H
18#define METROHASH_PLATFORM_H
19
20#include <stdint.h>
21#include <cstring>
22
23// rotate right idiom recognized by most compilers
24inline static uint64_t rotate_right(uint64_t v, unsigned k)
25{
26 return (v >> k) | (v << (64 - k));
27}
28
29inline static uint64_t read_u64(const void * const ptr)
30{
31 uint64_t result;
32 // Assignment like `result = *reinterpret_cast<const uint64_t *>(ptr)` here would mean undefined behaviour (unaligned read),
33 // so we use memcpy() which is the most portable. clang & gcc usually translates `memcpy()` into a single `load` instruction
34 // when hardware supports it, so using memcpy() is efficient too.
35 memcpy(&result, ptr, sizeof(result));
36 return result;
37}
38
39inline static uint64_t read_u32(const void * const ptr)
40{
41 uint32_t result;
42 memcpy(&result, ptr, sizeof(result));
43 return result;
44}
45
46inline static uint64_t read_u16(const void * const ptr)
47{
48 uint16_t result;
49 memcpy(&result, ptr, sizeof(result));
50 return result;
51}
52
53inline static uint64_t read_u8 (const void * const ptr)
54{
55 return static_cast<uint64_t>(*reinterpret_cast<const uint8_t *>(ptr));
56}
57
58
59#endif // #ifndef METROHASH_PLATFORM_H
60