aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yson_pull/detail/zigzag.h
blob: 4fca549f497e63a395c70864df2d29b85e018a45 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma once

#include "traits.h"

namespace NYsonPull { 
    namespace NDetail { 
        namespace NZigZag { 
            //! Functions that provide coding of integers with property: 0 <= f(x) <= 2 * |x| 

            template <typename TSigned>
            inline NTraits::to_unsigned<TSigned> encode(TSigned x) {
                using TUnsigned = NTraits::to_unsigned<TSigned>;
                constexpr auto rshift = sizeof(TSigned) * 8 - 1;
                return (static_cast<TUnsigned>(x) << 1) ^ static_cast<TUnsigned>(x >> rshift);
            } 

            template <typename TUnsigned>
            inline NTraits::to_signed<TUnsigned> decode(TUnsigned x) {
                using TSigned = NTraits::to_signed<TUnsigned>;
                return static_cast<TSigned>(x >> 1) ^ -static_cast<TSigned>(x & 1);
            } 
        } 
    }     // namespace NDetail 
}