Skip to content

Repository files navigation

comppath

comppath is a header-only C++ library for compile-time path manipulation.

All paths are processed entirely at compile time: a path is stored as a template parameter carrying a null-terminated string, and every operation is evaluated by the compiler. This means path parsing, decomposition, normalization and queries cost nothing at runtime. The resulting paths are proper compile-time constants and can be used anywhere a constant expression is required, for example as template arguments or to initialize static storage.

Platform support

The library works with two path flavors, differentiated by namespace:

  • comppath::posix — POSIX paths, stored as UTF-8
  • comppath::win — Windows paths, stored as UTF-16, with support for drive letters, UNC and device path root names as well as both \ and / separators

Path native for the current target platform and it's operations are exported into the plain comppath namespace, so on POSIX comppath::CompPath is comppath::posix::CompPath and on Windows it is comppath::win::CompPath. The other flavor remains available under its explicit namespace, which makes it possible to reason about foreign paths (for example in cross-platform tools) on any platform.

Operations

Most operations are done via constexpr constants rather than member functions. They are named after std::filesystem::path's methods and accomplish the same goal, so the semantics should feel familiar: PARENT_PATH, FILENAME, STEM, EXTENSION, ROOT_NAME, ROOT_DIRECTORY, ROOT_PATH, RELATIVE_PATH, REMOVE_FILENAME, REPLACE_FILENAME, REPLACE_EXTENSION, LEXICALLY_NORMAL, LEXICALLY_RELATIVE and others mirror their std::filesystem::path counterparts.

using namespace comppath;

constexpr auto path = CompPath{"/usr/local/bin"};
static_assert(ROOT_PATH<path> == "/");
static_assert(PARENT_PATH<path> == "/usr/local");
static_assert(FILENAME<path> == "bin");
static_assert(LEXICALLY_NORMAL<"/usr/./local/../lib"> == "/usr/lib");

Appending and concatenating paths is done with operator/ and operator+, mirroring std::filesystem::path:

constexpr auto config = CompPath{"etc"} / "app" / "app.conf"; // "etc/app/app.conf"
static_assert(REPLACE_EXTENSION<config, "cfg"> == "etc/app/app.cfg");

Dealing with bloat-capacity

Because constructors and operator/ have to reserve maximum possible capacity for result, some path's actual sizes may be smaller than their capacity, which can bloat binaries. In most cases inefficient storage shall not be a significant problem since operator/ only produces maximum of 1 byte of bloat if left-side path already ends with a separator (CompPath{"some/"} / "dir" ). What can produce a lot of bloat is constructing POSIX path from a UTF-32 string literal, which requires to reserve 4 times the UTF-32 codepoints amount for worst-case scenario. Other literal conversions also are also not great in that regard.

To keep your binaries efficient, apply SHRINK over constructed/appended CompPaths. Also note that all operations which are not methods of CompPath automatically apply SHRINK at the end which means that anything you get from them is stored efficiently even if an input is not optimized. Also it may be possible for some compilers to strip extra trailing zeroes from data in binary if they are not used for anything.

Accessing documentation

This project uses doxygen for documenting it's APIs. You can read docs in source code or read an index generated by xmake doxygen command. There is no remote docs index currently.

Installing

If you are an xmake user, add that to your project's xmake.lua:

add_repositories("comppath-repo [email protected]:bugsnotabunny/comppath.git v0.1.0")
add_requires("comppath v0.1.0", { external = true })

More complete example may be found here

If you are using anything other then xmake, following commands will generate you code for target build system:

xmake config --toolchain=clang --mode=release --tests=n
xmake project -k (cmake|make|ninja)

About

Header-only C++ library for compile-time path manipulation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages