/******************************************************************************/ /* FILESYSTEM ABSTRACTION *****************************************************/ /******************************************************************************/ #ifndef _H_EBCL_FILESYSTEM #define _H_EBCL_FILESYSTEM #include #include namespace ebcl { /*= FILESYSTEM PATH ==========================================================*/ // Supported filesystem path separators enum class E_FSPathSeparator { SLASH , BACKSLASH }; using T_OptPathSeparator = T_Optional< E_FSPathSeparator >; // The style of a filesystem path. class T_FSPathStyle { private: bool caseSensitive_; bool hasDriveLetter_; T_Flags< E_FSPathSeparator > pathSeparators_; public: //---------------------------------------------------------------------- // Constructors and assignment operators T_FSPathStyle( ) = delete; // Initialise the filesystem path style, specifying: // - whether it is case-sensitive, // - whether is can use a drive letter as its root, // - which separators it supports constexpr T_FSPathStyle( bool cs , bool hdl , T_Flags< E_FSPathSeparator > ps ) noexcept; // Default copy/move constructors/assignement operators constexpr T_FSPathStyle( T_FSPathStyle const& ) noexcept = default; constexpr T_FSPathStyle& operator =( T_FSPathStyle const& ) noexcept = default; constexpr T_FSPathStyle( T_FSPathStyle&& ) noexcept = default; constexpr T_FSPathStyle& operator =( T_FSPathStyle&& ) noexcept = default; T_FSPathStyle& swap( T_FSPathStyle& other ) noexcept; //---------------------------------------------------------------------- // Accessors constexpr bool caseSensitive( ) const noexcept; constexpr T_FSPathStyle& caseSensitive( bool cs ) noexcept; constexpr bool hasDriveLetter( ) const noexcept; constexpr T_FSPathStyle& hasDriveLetter( bool hdl ) noexcept; constexpr T_Flags< E_FSPathSeparator > pathSeparators( ) const noexcept; constexpr T_FSPathStyle& pathSeparator( T_Flags< E_FSPathSeparator > ps ) noexcept; //---------------------------------------------------------------------- // Checks constexpr bool isSeparator( T_Character chr ) const noexcept; bool isValidRoot( T_String const& string ) const noexcept; //---------------------------------------------------------------------- // Pre-initialised styles static constexpr T_FSPathStyle Unix( ); static constexpr T_FSPathStyle Windows( ); static constexpr T_FSPathStyle System( ); }; M_DECLARE_SWAP( T_FSPathStyle ); // Representation of a path class T_FSPath { public: using T_Components = T_AutoArray< T_String , 16 >; private: // Path style T_FSPathStyle style_; // Root will be '/' on Unix, or a drive letter on Windows. Relative // paths will have a blank root. T_String root_; T_Components components_; // Is the path valid? bool valid_; // String comparison helpers using F_StrCmp_ = int (*)( T_String const& , T_String const& ); F_StrCmp_ cmpFunction_( ) const noexcept; public: //---------------------------------------------------------------------- // Helpers static bool IsValidComponent( T_String const& string ) noexcept; //---------------------------------------------------------------------- // Basic constructors and assignment operators T_FSPath( T_FSPathStyle style = T_FSPathStyle::System( ) ) noexcept; T_FSPath( T_FSPath const& other ) noexcept; T_FSPath& operator =( T_FSPath const& other ) noexcept; T_FSPath( T_FSPath&& other ) noexcept; T_FSPath& operator =( T_FSPath&& other ) noexcept; T_FSPath& swap( T_FSPath& other ) noexcept; // Construct from a string T_FSPath( T_String const& path , T_FSPathStyle style = T_FSPathStyle::System( ) ) noexcept; //---------------------------------------------------------------------- bool isValid( ) const noexcept; T_FSPathStyle const& style( ) const noexcept; T_String const& root( ) const noexcept; T_Components const& components( ) const noexcept; bool isRelative( ) const noexcept; bool isAbsolute( ) const noexcept; //---------------------------------------------------------------------- // Convert the path into a string T_String toString( T_OptPathSeparator separator = {} ) const noexcept; // Compute a hash value for the path uint32_t computeHash( ) const noexcept; // Append to a string builder void appendTo( T_StringBuilder& sb , T_OptPathSeparator separator = {} ) const noexcept; // Comparisons. On Windows the comparison will be case-insensitive. int32_t compareTo( T_FSPath const& other ) const noexcept; bool operator ==( T_FSPath const& other ) const noexcept; bool operator !=( T_FSPath const& other ) const noexcept; bool operator <( T_FSPath const& other ) const noexcept; bool operator <=( T_FSPath const& other ) const noexcept; bool operator >( T_FSPath const& other ) const noexcept; bool operator >=( T_FSPath const& other ) const noexcept; //---------------------------------------------------------------------- // Returns the parent's path T_FSPath parent( ) const noexcept; // Returns the child's path T_FSPath child( T_String const& name ) const noexcept; // Appends the specified (relative) path to the current path and return // the result. If the path is absolute, the result will be invalid. T_FSPath operator +( T_FSPath const& other ) const noexcept; // Checks if the current path and the specified path have the same // parent and are different. bool inDirectoryOf( T_FSPath const& other ) const noexcept; // Checks if the current path is the direct parent of the specified path bool isParentOf( T_FSPath const& other ) const noexcept; // Checks if the current path is the direct child of the specified path bool isChildOf( T_FSPath const& other ) const noexcept; // Checks if the current path is a parent of the specified path bool isAbove( T_FSPath const& other ) const noexcept; // Checks if the current path is a child of the specified path bool isUnder( T_FSPath const& other ) const noexcept; // Create a relative path based on the current path and a "parent" path. // Both paths must be canonical and valid. If they have different roots, // a copy of the current path will be returned. T_FSPath makeRelative( T_FSPath const& relTo ) const noexcept; //---------------------------------------------------------------------- // Checks whether the specified path is canonical bool isCanonical( ) const noexcept; // Return a canonical path from the current path T_FSPath canonical( ) const noexcept; }; M_DECLARE_SWAP( T_FSPath ); M_DECLARE_HASH( T_FSPath ); M_LSHIFT_OP( T_StringBuilder , T_FSPath const& ); /*= FILESYSTEM ===============================================================*/ class Filesystem final { Filesystem( ) = delete; public: // Return the absolute path to the current working directory static T_FSPath Cwd( ) noexcept; }; } // namespace ebcl #endif // _H_EBCL_FILESYSTEM #include