aboutsummaryrefslogblamecommitdiffstats
path: root/util/system/src_root.h
blob: 4f2d9f5ee6c8f345f745b1f0789d0305c602b398 (plain) (tree)
1
2
3
4
5
6
7
8
9
            
                     
                     
 
                      
                       
                                                                     




                          
                                         


                                
                                               







                                                              
                                                                                 
 














                                                                                                             
         
                                           
         








                                                                                                        
     
 
                                                                                                                                                                     
#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)