aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/types.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/types.hxx')
-rw-r--r--libbuild2/types.hxx203
1 files changed, 136 insertions, 67 deletions
diff --git a/libbuild2/types.hxx b/libbuild2/types.hxx
index 0005e75..ea84701 100644
--- a/libbuild2/types.hxx
+++ b/libbuild2/types.hxx
@@ -15,6 +15,7 @@
#include <map>
#include <set>
+#include <list>
#include <array>
#include <tuple>
#include <regex>
@@ -29,14 +30,22 @@
#include <functional> // hash, function, reference_wrapper
#include <initializer_list>
-#include <mutex>
#include <atomic>
-#include <thread>
-#include <condition_variable>
-#include <libbutl/ft/shared_mutex.hxx>
-#if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex)
-# include <shared_mutex>
+#ifndef LIBBUTL_MINGW_STDTHREAD
+# include <mutex>
+# include <thread>
+# include <condition_variable>
+
+# include <libbutl/ft/shared_mutex.hxx>
+# if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex)
+# include <shared_mutex>
+# endif
+#else
+# include <libbutl/mingw-mutex.hxx>
+# include <libbutl/mingw-thread.hxx>
+# include <libbutl/mingw-condition_variable.hxx>
+# include <libbutl/mingw-shared_mutex.hxx>
#endif
#include <ios> // ios_base::failure
@@ -44,21 +53,22 @@
#include <stdexcept> // logic_error, invalid_argument, runtime_error
#include <system_error>
-#include <libbutl/path.mxx>
-#include <libbutl/path-map.mxx>
-#include <libbutl/regex.mxx>
-#include <libbutl/sha256.mxx>
-#include <libbutl/process.mxx>
-#include <libbutl/fdstream.mxx>
-#include <libbutl/optional.mxx>
-#include <libbutl/const-ptr.mxx>
-#include <libbutl/timestamp.mxx>
-#include <libbutl/vector-view.mxx>
-#include <libbutl/small-vector.mxx>
-#include <libbutl/project-name.mxx>
-#include <libbutl/target-triplet.mxx>
-#include <libbutl/semantic-version.mxx>
-#include <libbutl/standard-version.mxx>
+#include <libbutl/path.hxx>
+#include <libbutl/path-map.hxx>
+#include <libbutl/regex.hxx>
+#include <libbutl/sha256.hxx>
+#include <libbutl/process.hxx>
+#include <libbutl/fdstream.hxx>
+#include <libbutl/optional.hxx>
+#include <libbutl/const-ptr.hxx>
+#include <libbutl/timestamp.hxx>
+#include <libbutl/vector-view.hxx>
+#include <libbutl/small-vector.hxx>
+#include <libbutl/project-name.hxx>
+#include <libbutl/target-triplet.hxx>
+#include <libbutl/semantic-version.hxx>
+#include <libbutl/standard-version.hxx>
+#include <libbutl/move-only-function.hxx>
#include <libbuild2/export.hxx>
@@ -82,9 +92,12 @@ namespace build2
using std::pair;
using std::tuple;
using std::string;
- using std::function;
using std::reference_wrapper;
+ using std::function;
+ using butl::move_only_function;
+ using butl::move_only_function_ex;
+
using strings = std::vector<string>;
using cstrings = std::vector<const char*>;
@@ -102,8 +115,9 @@ namespace build2
using std::multiset;
using std::array;
using std::vector;
- using butl::vector_view; // <libbutl/vector-view.mxx>
- using butl::small_vector; // <libbutl/small-vector.mxx>
+ using std::list;
+ using butl::vector_view; // <libbutl/vector-view.hxx>
+ using butl::small_vector; // <libbutl/small-vector.hxx>
using std::istream;
using std::ostream;
@@ -112,7 +126,7 @@ namespace build2
// Regex.
//
- // Note that <libbutl/regex.mxx> includes an ostream insertion operator for
+ // Note that <libbutl/regex.hxx> includes an ostream insertion operator for
// regex_error which prints cleaned up message, if any.
//
using std::regex;
@@ -185,20 +199,27 @@ namespace build2
}
#endif
+#ifndef LIBBUTL_MINGW_STDTHREAD
using std::mutex;
using mlock = std::unique_lock<mutex>;
using std::condition_variable;
-#if defined(__cpp_lib_shared_mutex)
+ using std::defer_lock;
+ using std::adopt_lock;
+
+ using std::thread;
+ namespace this_thread = std::this_thread;
+
+# if defined(__cpp_lib_shared_mutex)
using shared_mutex = std::shared_mutex;
using ulock = std::unique_lock<shared_mutex>;
using slock = std::shared_lock<shared_mutex>;
-#elif defined(__cpp_lib_shared_timed_mutex)
+# elif defined(__cpp_lib_shared_timed_mutex)
using shared_mutex = std::shared_timed_mutex;
using ulock = std::unique_lock<shared_mutex>;
using slock = std::shared_lock<shared_mutex>;
-#else
+# else
// Because we have this fallback, we need to be careful not to create
// multiple shared locks in the same thread.
//
@@ -213,13 +234,57 @@ namespace build2
using ulock = std::unique_lock<shared_mutex>;
using slock = ulock;
-#endif
+# endif
+#else // LIBBUTL_MINGW_STDTHREAD
+ using mingw_stdthread::mutex;
+ using mlock = mingw_stdthread::unique_lock<mutex>;
- using std::defer_lock;
- using std::adopt_lock;
+ using mingw_stdthread::condition_variable;
- using std::thread;
- namespace this_thread = std::this_thread;
+ using mingw_stdthread::defer_lock;
+ using mingw_stdthread::adopt_lock;
+
+ using mingw_stdthread::thread;
+ namespace this_thread = mingw_stdthread::this_thread;
+
+ using shared_mutex = mingw_stdthread::shared_mutex;
+ using ulock = mingw_stdthread::unique_lock<shared_mutex>;
+ using slock = mingw_stdthread::shared_lock<shared_mutex>;
+#endif
+
+ // Global, MT-safe information cache. Normally used for caching information
+ // (versions, target triplets, search paths, etc) extracted from other
+ // programs (compilers, etc).
+ //
+ // The key is normally a hash of all the inputs that can affect the output.
+ //
+ // Note that insertion is racy and it's possible the cache entry already
+ // exists, in which case we ignore our value assuming it is the same.
+ //
+ template <typename T, typename K = string>
+ class global_cache
+ {
+ public:
+ const T*
+ find (const K& k) const
+ {
+ mlock l (mutex_);
+ auto i (cache_.find (k));
+ return i != cache_.end () ? &i->second : nullptr;
+ }
+
+ const T&
+ insert (K k, T v)
+ {
+ mlock l (mutex_);
+ return cache_.insert (std::make_pair (std::move (k),
+ std::move (v))).first->second;
+ }
+
+ private:
+ map<K, T> cache_;
+ mutable mutex mutex_;
+ };
// Exceptions.
//
@@ -232,17 +297,17 @@ namespace build2
using std::system_error;
using io_error = std::ios_base::failure;
- // <libbutl/optional.mxx>
+ // <libbutl/optional.hxx>
//
using butl::optional;
using butl::nullopt;
- // <libbutl/const-ptr.mxx>
+ // <libbutl/const-ptr.hxx>
//
using butl::const_ptr;
- // <libbutl/path.mxx>
- // <libbutl/path-map.mxx>
+ // <libbutl/path.hxx>
+ // <libbutl/path-map.hxx>
//
using butl::path;
using path_traits = path::traits_type;
@@ -258,6 +323,8 @@ namespace build2
using butl::path_map;
using butl::dir_path_map;
+ using butl::path_multimap;
+ using butl::dir_path_multimap;
// Absolute directory path. Note that for now we don't do any checking that
// the path is in fact absolute.
@@ -281,7 +348,21 @@ namespace build2
using paths = std::vector<path>;
using dir_paths = std::vector<dir_path>;
- // <libbutl/timestamp.mxx>
+ // Path printing potentially relative with trailing slash for directories.
+ //
+ LIBBUILD2_SYMEXPORT ostream&
+ operator<< (ostream&, const path&); // utility.cxx
+
+ inline ostream&
+ operator<< (ostream& os, const dir_path& d) // For overload resolution.
+ {
+ return build2::operator<< (os, static_cast<const path&> (d));
+ }
+
+ LIBBUILD2_SYMEXPORT ostream&
+ operator<< (ostream&, const path_name_view&); // utility.cxx
+
+ // <libbutl/timestamp.hxx>
//
using butl::system_clock;
using butl::timestamp;
@@ -293,13 +374,15 @@ namespace build2
using butl::to_string;
using butl::operator<<;
- // <libbutl/sha256.mxx>
+ // <libbutl/sha256.hxx>
//
using butl::sha256;
- // <libbutl/process.mxx>
+ // <libbutl/process.hxx>
+ //
using butl::process;
using butl::process_env;
+ using butl::process_exit;
using butl::process_path;
using butl::process_error;
@@ -345,8 +428,14 @@ namespace build2
process_path_ex () = default;
};
- // <libbutl/fdstream.mxx>
+ // Print as recall[@effect].
+ //
+ LIBBUILD2_SYMEXPORT ostream&
+ operator<< (ostream&, const process_path&); // utility.cxx
+
+ // <libbutl/fdstream.hxx>
//
+ using butl::nullfd;
using butl::auto_fd;
using butl::fdpipe;
using butl::ifdstream;
@@ -356,21 +445,21 @@ namespace build2
using butl::fdselect_state;
using butl::fdselect_set;
- // <libbutl/target-triplet.mxx>
+ // <libbutl/target-triplet.hxx>
//
using butl::target_triplet;
- // <libbutl/semantic-version.mxx>
+ // <libbutl/semantic-version.hxx>
//
using butl::semantic_version;
using butl::parse_semantic_version;
- // <libbutl/standard-version.mxx>
+ // <libbutl/standard-version.hxx>
//
using butl::standard_version;
using butl::standard_version_constraint;
- // <libbutl/project-name.mxx>
+ // <libbutl/project-name.hxx>
//
using butl::project_name;
@@ -428,9 +517,9 @@ namespace build2
location_value (const location&);
- location_value (location_value&&);
+ location_value (location_value&&) noexcept;
location_value (const location_value&);
- location_value& operator= (location_value&&);
+ location_value& operator= (location_value&&) noexcept;
location_value& operator= (const location_value&);
};
@@ -442,26 +531,6 @@ namespace build2
operator<< (ostream&, run_phase); // utility.cxx
}
-// In order to be found (via ADL) these have to be either in std:: or in
-// butl::. The latter is a bad idea since libbutl includes the default
-// implementation. They are defined in utility.cxx.
-//
-namespace std
-{
- // Path printing potentially relative with trailing slash for directories.
- //
- LIBBUILD2_SYMEXPORT ostream&
- operator<< (ostream&, const ::butl::path&);
-
- LIBBUILD2_SYMEXPORT ostream&
- operator<< (ostream&, const ::butl::path_name_view&);
-
- // Print as recall[@effect].
- //
- LIBBUILD2_SYMEXPORT ostream&
- operator<< (ostream&, const ::butl::process_path&);
-}
-
// <libbuild2/name.hxx>
//
#include <libbuild2/name.hxx>