Code Monkey home page Code Monkey logo

apathy's Introduction

Apathy Path Manipulation

I find myself occasionally needing to do path manipulation in C++, and while Boost.Filesystem is a useful tool, my qualm with it is that it requires Boost to be installed on the target system. For some cases, this is too large a requirement, and so I have often wanted this library.

Installation

Apathy is a header-only library, and so all you need to do is to include it in your code (this works particularly well with git submodules):

#include <apathy/path.hpp>

It imports a single member Path in the apathy namespace.

Usage

Most of the path manipulators return a reference to the current path, so that they can be chained:

/* Check if ./foo/bar exists */
Path::cwd().relative("foo").relative("bar").exists();
/* Make a sanitized absolute directory for ./foo///../a/b */
Path("./foo///../a/b").absolute().sanitize();

Operators

Path objects support the operators ==, !=, << (which appends to the path) and =:

/* Makes sure they're exact matches */
Path("./foo") == "./foo";
Path("./foo") != "foo";

/* Appends to the path */
Path p("foo");
p << "bar" << 5 << 3.1459 << Path("what");

In addition to these comparators, there's also an equivalent method that checks whether the two paths refer to the same resource. To do so, copies of both are made absolute and sanitized and then a strict string comparison is made:

/* These are equivalent, but not equal */
Path a("./foo////a/b/./d/../c");
Path b("foo/a/b/c");

/* These are true */
a.equivalent(b);
b.equivalent(a);
/* This is not */
a == b;

Modifiers

All of these methods modify the path they're associated with, and return a reference to the modified path so that they can be chained:

  • append -- appends a path segment to the current path:
/* Create a path to foo/bar/baz
Path p("foo");
std::cout << p.append("bar").append("baz").string() << std::endl;
/* Now p is "foo/bar/baz" */
  • relative -- evaluates one path relative to another. If the second path is an absolute path, then updates the object to point to that path:
/* Gives "foo/bar/whiz" */
Path("foo").relative("bar/whiz");
/* Gives "/bar/whiz" */
Path("foo").relative("/bar/whiz");
  • up -- move to the parent directory:
/* Gives /foo/bar/ */
Path("foo/bar/whiz").up();
  • absolute -- convert the path to an absolute path. If it's a relative path, then it's evaluated relative to the current working directory:
/* Gives <cwd>/foo/bar */
Path("foo/bar").absolute();
/* Gives /foo/bar */
Path("/foo/bar").absolute();
  • sanitize -- clean up repeated separators, evaluate .. and .. If .. is used to exceed the segments in a relative path, it is transformed into an absolute path. Otherwise, if it was a relative path, it remains a relative path afterwards:
/* Gives a/b/c/ */
Path("foo/.././a////b/d/../c");
  • directory -- ensure the path has a trailing separator to indicate it's a directory:
/* Gives a/b/c/ */
Path("a/b/c").directory();
  • trim -- removes any trailing separators from the path:
/* Gives a/b/c */
Path("a/b/c/////").trim();

Breaking It Down

There are a number of ways to get access to the various components of the path:

  • filename -- name of the file without any directories
  • extension -- get a string of the extension of the path (if any)
  • stem -- get a copy of the path without the extension
  • split -- each of the directories in the path

Copiers

While the modifiers change the instance itself and return a reference, some methods return a modified copy of the instance, leaving the original unchanged:

  • copy -- an easy shorthand for creating a copy of the path object, since it's common to chain methods. Consider:
/* I'd like to leave the original path unchanged */
Path p("foo/bar");
p.copy().absolute();

/* Equivalent to... */
Path(p).absolute();
  • parent -- returns a new path pointing to the parent directory:
/* Points to foo/bar, leaving original unchanged */
Path p("foo/bar/whiz");
p.parent();

Tests

You can run some simple checks about the path:

  • is_absolute -- if the path is an absolute path
  • trailing_slash -- if the path has a trailing slash

As well as get information about the filesystem:

  • exists -- returns true if path can successfully be stat-ed
  • is_directory -- returns true if the path exists and S_ISDIR
  • is_file -- returns true if the path exists and S_ISREG

Utility Functions

Lastly, there are a number of utility functions for dealing with paths and the filesystem:

  • cwd -- get a path that refers to the current working directory
  • touch -- update and make sure a file exists
  • makedirs -- attempt to recursively make a directory
  • rmdirs -- attempt to recursively remove a directory
  • listdir -- return a vector of all the paths in the provided directory

Roadmap

The interface is a little bit in flux, but I now need this code in more than one projects, so it was time for it to move into its own repository.

apathy's People

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.