aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/src_root.h
blob: 25f380f72352403dd74e1f4a8737b00fe5ad66d7 (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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#pragma once

#include "compiler.h"
#include "defaults.h"

#include <type_traits>

namespace NPrivate {
    struct TStaticBuf {
        constexpr TStaticBuf(const char* data, unsigned len) noexcept 
            : Data(data)
            , Len(len)
        {
        }

        template <class T>
        constexpr T As() const noexcept { 
            return T(Data, Len);
        }

        template <class T>
        constexpr operator T() const noexcept { 
            return this->As<T>();
        }

        const char* Data;
        unsigned Len;
    };

#define STATIC_BUF(x) ::NPrivate::TStaticBuf(x, sizeof(x) - 1)

    constexpr TStaticBuf ArcRoot = STATIC_BUF(Y_STRINGIZE(ARCADIA_ROOT));
    constexpr TStaticBuf BuildRoot = STATIC_BUF(Y_STRINGIZE(ARCADIA_BUILD_ROOT));

    constexpr Y_FORCE_INLINE bool IsProperPrefix(const TStaticBuf prefix, const TStaticBuf string) noexcept {
        if (prefix.Len < string.Len) {
            for (unsigned i = prefix.Len; i-- > 0;) {
                if (prefix.Data[i] != string.Data[i]) {
                    return false;
                }
            }
            return true;
        } else {
            return false;
        }
    }

    constexpr unsigned RootPrefixLength(const TStaticBuf& f) noexcept {
        if (IsProperPrefix(ArcRoot, f)) {
            return ArcRoot.Len + 1;
        }
        if (IsProperPrefix(BuildRoot, f)) {
            return BuildRoot.Len + 1;
        }
        return 0;
    }

    constexpr Y_FORCE_INLINE TStaticBuf StripRoot(const TStaticBuf& f, unsigned prefixLength) noexcept {
        return TStaticBuf(f.Data + prefixLength, f.Len - prefixLength);
    }

    //$(SRC_ROOT)/prj/blah.cpp -> prj/blah.cpp
    constexpr Y_FORCE_INLINE TStaticBuf StripRoot(const TStaticBuf& f) noexcept {
        return StripRoot(f, RootPrefixLength(f));
    }
}

#define __SOURCE_FILE_IMPL__ ::NPrivate::StripRoot(STATIC_BUF(__FILE__), std::integral_constant<unsigned, ::NPrivate::RootPrefixLength(STATIC_BUF(__FILE__))>::value)