diff options
-rw-r--r-- | libbutl/default-options.cxx | 73 | ||||
-rw-r--r-- | libbutl/default-options.mxx | 23 | ||||
-rw-r--r-- | libbutl/default-options.txx | 39 | ||||
-rw-r--r-- | tests/default-options/driver.cxx | 2 |
4 files changed, 58 insertions, 79 deletions
diff --git a/libbutl/default-options.cxx b/libbutl/default-options.cxx deleted file mode 100644 index 28f6fb7..0000000 --- a/libbutl/default-options.cxx +++ /dev/null @@ -1,73 +0,0 @@ -// file : libbutl/default-options.cxx -*- C++ -*- -// license : MIT; see accompanying LICENSE file - -#ifndef __cpp_modules_ts -#include <libbutl/default-options.mxx> -#endif - -#include <cassert> - -#ifndef __cpp_lib_modules_ts -#include <vector> -#endif - -// Other includes. - -#ifdef __cpp_modules_ts -module butl.default_options; - -// Only imports additional to interface. -#ifdef __clang__ -#ifdef __cpp_lib_modules_ts -import std.core; -#endif -import butl.path; -import butl.optional; -import butl.small_vector; -#endif - -#endif - -using namespace std; - -namespace butl -{ - optional<dir_path> - default_options_start (const optional<dir_path>& home, - const vector<dir_path>& dirs) - { - if (home) - assert (home->absolute () && home->normalized ()); - - if (dirs.empty ()) - return nullopt; - - // Use the first directory as a start. - // - auto i (dirs.begin ()); - dir_path d (*i); - - // Try to find a common prefix for each subsequent directory. - // - for (++i; i != dirs.end (); ++i) - { - bool p (false); - - for (; - !(d.root () || (home && d == *home)); - d = d.directory ()) - { - if (i->sub (d)) - { - p = true; - break; - } - } - - if (!p) - return nullopt; - } - - return d; - } -} diff --git a/libbutl/default-options.mxx b/libbutl/default-options.mxx index 11f7bb2..2d44333 100644 --- a/libbutl/default-options.mxx +++ b/libbutl/default-options.mxx @@ -152,12 +152,25 @@ LIBBUTL_MODEXPORT namespace butl AS merge_default_arguments (const default_options<O>&, const AS&, F&&); - // Find a common start (parent) directory stopping at home or root - // (excluding). + // Find a common start (parent) directory for directories specified as an + // iterator range, stopping at home or root (excluding). Optionally pass a + // function resolving an iterator into a directory in a way other than just + // dereferencing it. The function signature is: // - LIBBUTL_SYMEXPORT optional<dir_path> - default_options_start (const optional<dir_path>& home_dir, - const std::vector<dir_path>&); + // const dir_path& (I) + // + template <typename I, typename F> + optional<dir_path> + default_options_start (const optional<dir_path>& home, I, I, F&&); + + template <typename I> + inline optional<dir_path> + default_options_start (const optional<dir_path>& home, I b, I e) + { + return default_options_start (home, + b, e, + [] (I i) -> const dir_path& {return *i;}); + } } #include <libbutl/default-options.ixx> diff --git a/libbutl/default-options.txx b/libbutl/default-options.txx index eaf4235..dc809ad 100644 --- a/libbutl/default-options.txx +++ b/libbutl/default-options.txx @@ -318,4 +318,43 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason. r.insert (r.end (), cmd_args.begin (), cmd_args.end ()); return r; } + + template <typename I, typename F> + optional<dir_path> + default_options_start (const optional<dir_path>& home, I b, I e, F&& f) + { + if (home) + assert (home->absolute () && home->normalized ()); + + if (b == e) + return nullopt; + + // Use the first directory as a start. + // + I i (b); + dir_path d (f (i)); + + // Try to find a common prefix for each subsequent directory. + // + for (++i; i != e; ++i) + { + bool p (false); + + for (; + !(d.root () || (home && d == *home)); + d = d.directory ()) + { + if (f (i).sub (d)) + { + p = true; + break; + } + } + + if (!p) + return nullopt; + } + + return d; + } } diff --git a/tests/default-options/driver.cxx b/tests/default-options/driver.cxx index b3f66bf..009cddb 100644 --- a/tests/default-options/driver.cxx +++ b/tests/default-options/driver.cxx @@ -250,7 +250,7 @@ main (int argc, const char* argv[]) // Deduce a common start directory. // - fs.start = default_options_start (home_dir, dirs); + fs.start = default_options_start (home_dir, dirs.begin (), dirs.end ()); // Load and print the default options. // |