23#ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_PATH_IMPL_
24#error "This file should not be included directly! Use ElementsKernel/Path.h instead"
30#include <unordered_set>
34#include <boost/algorithm/string.hpp>
35#include <boost/filesystem/operations.hpp>
36#include <boost/filesystem/path.hpp>
42template <
typename T,
typename U>
46 Item file_path{file_name};
48 auto found_pos = std::find_if(locations.cbegin(), locations.cend(), [file_path](
const U& l) {
49 return boost::filesystem::exists(Item{l} / file_path);
52 if (found_pos != locations.cend()) {
53 found_path =
Item{*found_pos} / file_path;
59template <
typename T,
typename U>
62 std::vector<Item> file_list(locations.size());
63 Item file_path{file_name};
65 std::transform(locations.cbegin(), locations.cend(), file_list.begin(), [file_path](
const U& l) {
66 return Item{l} / file_path;
69 auto found_pos = std::remove_if(file_list.begin(), file_list.end(), [](
const Item& p) {
70 return not boost::filesystem::exists(p);
73 file_list.erase(found_pos, file_list.end());
89std::string
joinPath(
const std::vector<T>& path_list) {
94 vector<string> elems(path_list.size());
96 std::transform(path_list.cbegin(), path_list.cend(), elems.begin(), [](
const T& s) {
97 return Item{s}.string();
100 string result = boost::algorithm::join(elems, PATH_SEP);
105template <
typename... Args>
106auto join(Args&&... args) ->
decltype(
joinPath(std::forward<Args>(args)...)) {
107 return joinPath(std::forward<Args>(args)...);
110template <
typename... Args>
111auto split(Args&&... args) ->
decltype(
splitPath(std::forward<Args>(args)...)) {
112 return splitPath(std::forward<Args>(args)...);
115template <
typename T,
typename U>
116std::vector<Item>
multiPathAppend(
const std::vector<T>& initial_locations,
const std::vector<U>& suffixes) {
120 vector<Item> result(initial_locations.size() * suffixes.size());
122 auto pos = result.begin();
124 std::for_each(initial_locations.cbegin(), initial_locations.cend(), [&pos, &suffixes](
const T& l) {
125 std::transform(suffixes.cbegin(), suffixes.cend(), pos, [l](const U& s) {
128 pos +=
static_cast<std::ptrdiff_t
>(suffixes.size());
137 std::unordered_set<std::string>
s;
139 std::vector<Item> output(path_list.size());
141 auto end = std::copy_if(path_list.cbegin(), path_list.cend(), output.begin(), [&s](
const T& i) {
142 return s.insert(Item{i}.string()).second;
145 output.erase(end, output.end());
ELEMENTS_API std::vector< Item > getAllPathFromLocations(const T &file_name, const std::vector< U > &locations)
retrieve all the paths from a file name and a set of location to look into
ELEMENTS_API std::vector< Item > getLocationsFromEnv(const std::string &path_variable, bool exist_only=false)
function to get the locations from an environment variable
ELEMENTS_API auto join(Args &&... args) -> decltype(joinPath(std::forward< Args >(args)...))
alias for the joinPath function
ELEMENTS_API std::vector< Item > removeDuplicates(const std::vector< T > &path_list)
remove duplicated paths keeping the order
ELEMENTS_API std::string joinPath(const std::vector< T > &path_list)
collate a vector of path into a string using PATH_SEP
ELEMENTS_API auto split(Args &&... args) -> decltype(splitPath(std::forward< Args >(args)...))
alias for the splitPath function
ELEMENTS_API Item getPathFromLocations(const T &file_name, const std::vector< U > &locations)
retrieve path from a file name and a set of location to look into
ELEMENTS_API std::vector< Item > splitPath(const std::string &path_string)
split a string into a vector of path using PATH_SEP
ELEMENTS_API Item getPathFromEnvVariable(const T &file_name, const std::string &path_variable)
retrieve path from a file name and an environment variable to look into
ELEMENTS_API std::vector< Item > multiPathAppend(const std::vector< T > &initial_locations, const std::vector< U > &suffixes)
path join each suffix to each initial locations
boost::filesystem::path Item