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