libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

file.hpp (2387B)


      1 #ifndef UUID_4C4561D8_78E4_438B_9804_61F42DB159F7
      2 #define UUID_4C4561D8_78E4_438B_9804_61F42DB159F7
      3 #pragma once
      4 
      5 #include "libshit/meta_utils.hpp" // IWYU pragma: export
      6 #include "libshit/platform.hpp"
      7 
      8 #include <boost/mp11/algorithm.hpp>
      9 #include <boost/mp11/list.hpp>
     10 
     11 #include <type_traits>
     12 
     13 // IWYU pragma: no_include <boost/mp11/integral.hpp> // namespace alias...
     14 
     15 namespace Libshit::FileTools
     16 {
     17   namespace mp = boost::mp11;
     18 
     19   template <char Val> using C = std::integral_constant<char, Val>;
     20   template <char... Vals> using CL = mp::mp_list_c<char, Vals...>;
     21 
     22 
     23   template <typename State, typename Elem> struct FoldImpl
     24   { using type = mp::mp_push_back<State, Elem>; };
     25   // ignore empty components (a//b or absolute path). shouldn't really happen.
     26   template <typename State> struct FoldImpl<State, CL<>>
     27   { using type = State; };
     28   // ignore .
     29   template <typename State> struct FoldImpl<State, CL<'.'>>
     30   { using type = State; };
     31   // .. eats a directory
     32   template <typename State> struct FoldImpl<State, CL<'.','.'>>
     33   { using type = mp::mp_pop_back<State>; };
     34   // except if state already empty
     35   template <> struct FoldImpl<CL<>, CL<'.','.'>>
     36   { using type = mp::mp_list<CL<'.', '.'>>; };
     37 
     38   // ignore everything before src/ext
     39   template <typename State> struct FoldImpl<State, CL<'s','r','c'>>
     40   { using type = CL<>; };
     41   template <typename State> struct FoldImpl<State, CL<'e','x','t'>>
     42   { using type = CL<>; };
     43 
     44   template <typename State, typename Elem>
     45   using Fold = typename FoldImpl<State, Elem>::type;
     46 
     47 
     48   template <typename X> struct LWrap;
     49   template <char... Chars> struct LWrap<CL<Chars...>>
     50   { using type = StringContainer<Chars...>; };
     51 
     52   template <typename X> using Wrap = typename LWrap<X>::type;
     53 
     54   template <char... Args>
     55   using FileName =
     56     Wrap<mp::mp_join<mp::mp_fold<
     57                 mp::mp_split<CL<Args...>, C<'/'>>, CL<>, Fold>, C<'/'>>>;
     58 }
     59 
     60 #  define LIBSHIT_FILE \
     61   LIBSHIT_LITERAL_CHARPACK(::Libshit::FileTools::FileName, __FILE__).str
     62 #  define LIBSHIT_WFILE \
     63   LIBSHIT_LITERAL_CHARPACK(::Libshit::FileTools::FileName, __FILE__).wstr
     64 
     65 // boost doesn't check __clang__, and falls back to some simpler implementation
     66 #if LIBSHIT_COMPILER_IS_GCC || LIBSHIT_COMPILER_IS_CLANG
     67 #  define LIBSHIT_FUNCTION __PRETTY_FUNCTION__
     68 #else
     69 #  include <boost/current_function.hpp>
     70 #  define LIBSHIT_FUNCTION BOOST_CURRENT_FUNCTION
     71 #endif
     72 
     73 #endif