diff options
Diffstat (limited to 'build2/name')
-rw-r--r-- | build2/name | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/build2/name b/build2/name new file mode 100644 index 0000000..a0672c7 --- /dev/null +++ b/build2/name @@ -0,0 +1,113 @@ +// file : build2/name -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD2_NAME +#define BUILD2_NAME + +#include <string> +#include <vector> +#include <iosfwd> +#include <utility> // move() + +#include <butl/path> + +// Note: include <build2/types> instead of this file directly. +// +namespace build2 +{ + using butl::dir_path; + + // A name is what we operate on by default. Depending on the context, + // it can be interpreted as a target or prerequisite name. A name + // without a type and directory can be used to represent any text. + // A name with directory and empty value represents a directory. + // A name may also be project-qualified. If the project name is + // empty, then it means the name is in a project other than our + // own (e.g., it is installed). + // + // If pair is not '\0', then this name and the next in the list + // form a pair. + // + struct name + { + name () = default; + + explicit name (std::string v): value (std::move (v)) {} + name& operator= (std::string v) {return *this = name (std::move (v));} + + explicit name (dir_path d): dir (std::move (d)) {} + name& operator= (dir_path d) {return *this = name (std::move (d));} + + name (std::string t, std::string v) + : type (std::move (t)), value (std::move (v)) {} + + name (dir_path d, std::string t, std::string v) + : dir (std::move (d)), type (std::move (t)), value (std::move (v)) {} + + // The first argument should be from project_name_pool. + // + name (const std::string* p, dir_path d, std::string t, std::string v) + : proj (p), + dir (std::move (d)), + type (std::move (t)), + value (std::move (v)) {} + + bool + qualified () const {return proj != nullptr;} + + bool + unqualified () const {return proj == nullptr;} + + bool + typed () const {return !type.empty ();} + + bool + untyped () const {return type.empty ();} + + bool + empty () const {return dir.empty () && value.empty ();} + + // Note that strictly speaking the following tests should be + // orthogonal to qualification. However, the vast majority of + // cases where we expect a simple or directory name, we also + // expect it to be unqualified. + // + // Note also that empty name is simple but not a directory. + // + bool + simple () const {return unqualified () && untyped () && dir.empty ();} + + bool + directory () const + {return unqualified () && untyped () && !dir.empty () && value.empty ();} + + const std::string* proj = nullptr; // Points to project_name_pool. + dir_path dir; + std::string type; + std::string value; + char pair = '\0'; // Pair symbol, if any. + }; + + inline bool + operator== (const name& x, const name& y) + { + return x.proj == y.proj && // Pooled, so can just compare pointers. + x.type == y.type && + x.dir == y.dir && + x.value == y.value; + } + + inline bool + operator!= (const name& x, const name& y) {return !(x == y);} + + typedef std::vector<name> names; + + std::ostream& + operator<< (std::ostream&, const name&); + + std::ostream& + operator<< (std::ostream&, const names&); +} + +#endif // BUILD2_NAME |