From 7a7b8ba432977282a90567c77822a72645d2a5c8 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 9 Apr 2016 07:48:02 +0200 Subject: Add abs_dir_path type, auto-complete if initialized from names --- build2/parser.cxx | 21 +++++++++++---------- build2/types | 18 +++++++++++++++++- build2/variable | 17 +++++++++++++++++ build2/variable.cxx | 28 ++++++++++++++++++++++++++++ build2/variable.ixx | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 11 deletions(-) diff --git a/build2/parser.cxx b/build2/parser.cxx index 3d21cac..6926ce3 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -1335,16 +1335,17 @@ namespace build2 map_type (const string& n) { return - n == "bool" ? &value_traits::value_type : - n == "uint64" ? &value_traits::value_type : - n == "string" ? &value_traits::value_type : - n == "path" ? &value_traits::value_type : - n == "dir_path" ? &value_traits::value_type : - n == "name" ? &value_traits::value_type : - n == "strings" ? &value_traits::value_type : - n == "paths" ? &value_traits::value_type : - n == "dir_paths" ? &value_traits::value_type : - n == "names" ? &value_traits::value_type : + n == "bool" ? &value_traits::value_type : + n == "uint64" ? &value_traits::value_type : + n == "string" ? &value_traits::value_type : + n == "path" ? &value_traits::value_type : + n == "dir_path" ? &value_traits::value_type : + n == "abs_dir_path" ? &value_traits::value_type : + n == "name" ? &value_traits::value_type : + n == "strings" ? &value_traits::value_type : + n == "paths" ? &value_traits::value_type : + n == "dir_paths" ? &value_traits::value_type : + n == "names" ? &value_traits::value_type : nullptr; } diff --git a/build2/types b/build2/types index 166f47a..d3930ba 100644 --- a/build2/types +++ b/build2/types @@ -8,7 +8,7 @@ #include #include #include // unique_ptr, shared_ptr -#include // pair +#include // pair, move() #include // size_t, nullptr_t #include // uint{8,16,32,64}_t #include @@ -77,6 +77,22 @@ namespace build2 using butl::basic_path; using butl::invalid_path; + // Absolute directory path. Note that for now we don't do any checking that + // the path is in fact absolute. + // + // The idea is to have a different type that we automatically complete when + // a (variable) value of this type gets initialized from untyped names. See + // value_type for details. + // + struct abs_dir_path: dir_path + { + using dir_path::dir_path; + + explicit + abs_dir_path (dir_path d): dir_path (std::move (d).string (), false) {} + abs_dir_path () = default; + }; + using paths = std::vector; using dir_paths = std::vector; diff --git a/build2/variable b/build2/variable index a3c1ea6..5a33037 100644 --- a/build2/variable +++ b/build2/variable @@ -479,6 +479,23 @@ namespace build2 static const build2::value_type value_type; }; + // abs_dir_path + // + template <> + struct value_traits + { + static_assert (sizeof (abs_dir_path) <= value::size_, + "insufficient space"); + + static abs_dir_path convert (name&&, name*); + static bool assign (value&, abs_dir_path&&); + static bool append (value&, abs_dir_path&&); // operator/ + static name reverse (const abs_dir_path& x) {return name (x);} + static int compare (const abs_dir_path&, const abs_dir_path&); + + static const build2::value_type value_type; + }; + // name // template <> diff --git a/build2/variable.cxx b/build2/variable.cxx index da7446d..61f5975 100644 --- a/build2/variable.cxx +++ b/build2/variable.cxx @@ -526,6 +526,34 @@ namespace build2 &simple_compare }; + // abs_dir_path value + // + abs_dir_path value_traits:: + convert (name&& n, name* r) + { + dir_path d (value_traits::convert (move (n), r)); + + if (d.relative ()) + d.complete (); + + return abs_dir_path (move (d)); + } + + const value_type value_traits::value_type + { + "abs_dir_path", + sizeof (abs_dir_path), + &default_dtor, + &default_copy_ctor, + &default_copy_assign, + &simple_assign, // Allow empty paths. + &simple_append, + nullptr, // No prepend. + &simple_reverse, + nullptr, // No cast (cast data_ directly). + &simple_compare + }; + // name value // name value_traits:: diff --git a/build2/variable.ixx b/build2/variable.ixx index 821d224..e52a150 100644 --- a/build2/variable.ixx +++ b/build2/variable.ixx @@ -411,6 +411,47 @@ namespace build2 return l.compare (r); } + // abs_dir_path value + // + inline bool value_traits:: + assign (value& v, abs_dir_path&& x) + { + abs_dir_path* p; + + if (v.null ()) + p = new (&v.data_) abs_dir_path (move (x)); + else + p = &(v.as () = move (x)); + + return !p->empty (); + } + + inline bool value_traits:: + append (value& v, abs_dir_path&& x) + { + abs_dir_path* p; + + if (v.null ()) + p = new (&v.data_) abs_dir_path (move (x)); + else + { + p = &v.as (); + + if (p->empty ()) + p->swap (x); + else + *p /= x; + } + + return !p->empty (); + } + + inline int value_traits:: + compare (const abs_dir_path& l, const abs_dir_path& r) + { + return l.compare (static_cast (r)); + } + // name value // inline bool value_traits:: -- cgit v1.1