aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-09-22 23:32:28 +0200
commitc09cd7512491cee1e82c1ad8128ce9fd4bc3f79b (patch)
treea659ed768d849130ab5780a11b7f791a463a1a91
parent2a00871f07067f8f9e2de08bb9c8f50e1bf6a650 (diff)
Initial modularization with both Clang and VC hacks
Note: gave up on VC about half way though.
-rw-r--r--build/root.build5
-rw-r--r--libbutl/base64.cxx26
-rw-r--r--libbutl/base64.mxx (renamed from libbutl/base64.hxx)25
-rw-r--r--libbutl/buildfile18
-rw-r--r--libbutl/char-scanner.cxx28
-rw-r--r--libbutl/char-scanner.mxx (renamed from libbutl/char-scanner.hxx)28
-rw-r--r--libbutl/const-ptr.mxx (renamed from libbutl/const-ptr.hxx)26
-rw-r--r--libbutl/curl.cxx33
-rw-r--r--libbutl/curl.ixx5
-rw-r--r--libbutl/curl.mxx (renamed from libbutl/curl.hxx)41
-rw-r--r--libbutl/curl.txx5
-rw-r--r--libbutl/diagnostics.cxx37
-rw-r--r--libbutl/diagnostics.mxx (renamed from libbutl/diagnostics.hxx)28
-rw-r--r--libbutl/export.hxx9
-rw-r--r--libbutl/fdstream.cxx35
-rw-r--r--libbutl/fdstream.ixx3
-rw-r--r--libbutl/fdstream.mxx (renamed from libbutl/fdstream.hxx)41
-rw-r--r--libbutl/filesystem.cxx47
-rw-r--r--libbutl/filesystem.ixx2
-rw-r--r--libbutl/filesystem.mxx (renamed from libbutl/filesystem.hxx)41
-rw-r--r--libbutl/ft/exception.hxx7
-rw-r--r--libbutl/ft/shared_mutex.hxx7
-rw-r--r--libbutl/manifest-forward.hxx5
-rw-r--r--libbutl/manifest-parser.cxx30
-rw-r--r--libbutl/manifest-parser.mxx (renamed from libbutl/manifest-parser.hxx)30
-rw-r--r--libbutl/manifest-serializer.cxx31
-rw-r--r--libbutl/manifest-serializer.mxx (renamed from libbutl/manifest-serializer.hxx)25
-rw-r--r--libbutl/multi-index.mxx (renamed from libbutl/multi-index.hxx)28
-rw-r--r--libbutl/openssl.cxx28
-rw-r--r--libbutl/openssl.ixx5
-rw-r--r--libbutl/openssl.mxx (renamed from libbutl/openssl.hxx)40
-rw-r--r--libbutl/openssl.txx4
-rw-r--r--libbutl/optional.mxx (renamed from libbutl/optional.hxx)31
-rw-r--r--libbutl/pager.cxx51
-rw-r--r--libbutl/pager.mxx (renamed from libbutl/pager.hxx)33
-rw-r--r--libbutl/path-io.mxx (renamed from libbutl/path-io.hxx)30
-rw-r--r--libbutl/path-map.mxx (renamed from libbutl/path-map.hxx)32
-rw-r--r--libbutl/path.cxx45
-rw-r--r--libbutl/path.ixx28
-rw-r--r--libbutl/path.mxx (renamed from libbutl/path.hxx)55
-rw-r--r--libbutl/path.txx10
-rw-r--r--libbutl/prefix-map.mxx (renamed from libbutl/prefix-map.hxx)26
-rw-r--r--libbutl/prefix-map.txx2
-rw-r--r--libbutl/process-details.hxx13
-rw-r--r--libbutl/process-io.hxx28
-rw-r--r--libbutl/process-io.mxx44
-rw-r--r--libbutl/process-run.cxx27
-rw-r--r--libbutl/process-run.txx5
-rw-r--r--libbutl/process.cxx74
-rw-r--r--libbutl/process.ixx9
-rw-r--r--libbutl/process.mxx (renamed from libbutl/process.hxx)46
-rw-r--r--libbutl/regex.cxx35
-rw-r--r--libbutl/regex.ixx4
-rw-r--r--libbutl/regex.mxx (renamed from libbutl/regex.hxx)38
-rw-r--r--libbutl/regex.txx5
-rw-r--r--libbutl/sendmail.cxx27
-rw-r--r--libbutl/sendmail.ixx5
-rw-r--r--libbutl/sendmail.mxx (renamed from libbutl/sendmail.hxx)38
-rw-r--r--libbutl/sha256.cxx69
-rw-r--r--libbutl/sha256.mxx (renamed from libbutl/sha256.hxx)41
-rw-r--r--libbutl/small-vector.mxx (renamed from libbutl/small-vector.hxx)29
-rw-r--r--libbutl/standard-version.cxx34
-rw-r--r--libbutl/standard-version.mxx (renamed from libbutl/standard-version.hxx)30
-rw-r--r--libbutl/string-parser.cxx193
-rw-r--r--libbutl/string-parser.mxx (renamed from libbutl/string-parser.hxx)49
-rw-r--r--libbutl/string-table.mxx (renamed from libbutl/string-table.hxx)42
-rw-r--r--libbutl/string-table.txx4
-rw-r--r--libbutl/tab-parser.cxx35
-rw-r--r--libbutl/tab-parser.mxx (renamed from libbutl/tab-parser.hxx)27
-rw-r--r--libbutl/target-triplet.cxx26
-rw-r--r--libbutl/target-triplet.mxx (renamed from libbutl/target-triplet.hxx)28
-rw-r--r--libbutl/timestamp.cxx270
-rw-r--r--libbutl/timestamp.mxx (renamed from libbutl/timestamp.hxx)40
-rw-r--r--libbutl/utility.cxx28
-rw-r--r--libbutl/utility.ixx8
-rw-r--r--libbutl/utility.mxx (renamed from libbutl/utility.hxx)59
-rw-r--r--libbutl/vector-view.mxx (renamed from libbutl/vector-view.hxx)26
-rw-r--r--libbutl/version.hxx.in4
-rw-r--r--libbutl/win32-utility.cxx4
-rw-r--r--libbutl/win32-utility.hxx9
-rw-r--r--tests/base64/buildfile6
-rw-r--r--tests/base64/driver.cxx18
-rw-r--r--tests/build/root.build5
-rw-r--r--tests/cpfile/buildfile6
-rw-r--r--tests/cpfile/driver.cxx23
-rw-r--r--tests/curl/buildfile6
-rw-r--r--tests/curl/driver.cxx31
-rw-r--r--tests/dir-iterator/buildfile6
-rw-r--r--tests/dir-iterator/driver.cxx26
-rw-r--r--tests/fdstream/buildfile6
-rw-r--r--tests/fdstream/driver.cxx32
-rw-r--r--tests/link/buildfile6
-rw-r--r--tests/link/driver.cxx22
-rw-r--r--tests/manifest-parser/buildfile6
-rw-r--r--tests/manifest-parser/driver.cxx19
-rw-r--r--tests/manifest-roundtrip/buildfile6
-rw-r--r--tests/manifest-roundtrip/driver.cxx25
-rw-r--r--tests/manifest-serializer/buildfile6
-rw-r--r--tests/manifest-serializer/driver.cxx19
-rw-r--r--tests/mventry/buildfile6
-rw-r--r--tests/mventry/driver.cxx22
-rw-r--r--tests/openssl/buildfile6
-rw-r--r--tests/openssl/driver.cxx28
-rw-r--r--tests/pager/buildfile6
-rw-r--r--tests/pager/driver.cxx19
-rw-r--r--tests/path-entry/buildfile6
-rw-r--r--tests/path-entry/driver.cxx21
-rw-r--r--tests/path/buildfile6
-rw-r--r--tests/path/driver.cxx18
-rw-r--r--tests/prefix-map/buildfile6
-rw-r--r--tests/prefix-map/driver.cxx19
-rw-r--r--tests/process-run/buildfile6
-rw-r--r--tests/process-run/driver.cxx27
-rw-r--r--tests/process/buildfile6
-rw-r--r--tests/process/driver.cxx27
-rw-r--r--tests/progress/buildfile6
-rw-r--r--tests/progress/driver.cxx35
-rw-r--r--tests/regex/buildfile6
-rw-r--r--tests/regex/driver.cxx20
-rw-r--r--tests/sendmail/buildfile6
-rw-r--r--tests/sendmail/driver.cxx28
-rw-r--r--tests/sha256/buildfile6
-rw-r--r--tests/sha256/driver.cxx19
-rw-r--r--tests/small-vector/buildfile6
-rw-r--r--tests/small-vector/driver.cxx20
-rw-r--r--tests/standard-version/buildfile6
-rw-r--r--tests/standard-version/driver.cxx22
-rw-r--r--tests/strcase/buildfile6
-rw-r--r--tests/strcase/driver.cxx16
-rw-r--r--tests/string-parser/buildfile6
-rw-r--r--tests/string-parser/driver.cxx28
-rw-r--r--tests/tab-parser/buildfile6
-rw-r--r--tests/tab-parser/driver.cxx20
-rw-r--r--tests/target-triplet/buildfile6
-rw-r--r--tests/target-triplet/driver.cxx18
-rw-r--r--tests/timestamp/buildfile6
-rw-r--r--tests/timestamp/driver.cxx17
-rw-r--r--tests/wildcard/buildfile6
-rw-r--r--tests/wildcard/driver.cxx28
139 files changed, 2526 insertions, 839 deletions
diff --git a/build/root.build b/build/root.build
index 84c236f..5129a40 100644
--- a/build/root.build
+++ b/build/root.build
@@ -2,6 +2,11 @@
# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
+using cxx.guess
+
+if ($force_modules != true && $cxx.id == 'clang')
+ cxx.features.modules = false
+
cxx.std = experimental
using cxx
diff --git a/libbutl/base64.cxx b/libbutl/base64.cxx
index 580090c..a8f7757 100644
--- a/libbutl/base64.cxx
+++ b/libbutl/base64.cxx
@@ -2,13 +2,37 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/base64.hxx>
+#ifndef __cpp_modules
+#include <libbutl/base64.mxx>
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
#include <cstddef> // size_t
#include <istream>
#include <ostream>
#include <iterator> // {istreambuf, ostreambuf, back_insert}_iterator
#include <stdexcept> // invalid_argument
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.base64;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+#endif
using namespace std;
diff --git a/libbutl/base64.hxx b/libbutl/base64.mxx
index 748dcfa..ae43ba6 100644
--- a/libbutl/base64.hxx
+++ b/libbutl/base64.mxx
@@ -1,17 +1,32 @@
-// file : libbutl/base64.hxx -*- C++ -*-
+// file : libbutl/base64.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_BASE64_HXX
-#define LIBBUTL_BASE64_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <iosfwd>
#include <string>
#include <vector>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.base64;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Base64-encode a stream or a buffer. Split the output into 76 char-long
// lines (new line is the 77th). If reading from a stream, check if it has
@@ -46,5 +61,3 @@ namespace butl
LIBBUTL_SYMEXPORT std::vector<char>
base64_decode (const std::string&);
}
-
-#endif // LIBBUTL_BASE64_HXX
diff --git a/libbutl/buildfile b/libbutl/buildfile
index fe2e606..6086fd7 100644
--- a/libbutl/buildfile
+++ b/libbutl/buildfile
@@ -2,7 +2,16 @@
# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-lib{butl}: {hxx ixx txx cxx}{** -win32-utility -version} {hxx}{version}
+int_libs =
+
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import int_libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
+lib{butl}: {mxx hxx ixx txx cxx}{** -win32-utility -version} {hxx}{version} \
+ $int_libs
# Exclude these from compilation on non-Windows targets.
#
@@ -33,7 +42,7 @@ if $version.pre_release
else
lib{butl}: bin.lib.version = @"-$version.major.$version.minor"
-bmi{*}: cxx.poptions += -DLIBBUTL_MODULE_BUILD
+lib{butl}: cxx.export.libs = $int_libs
cxx.poptions =+ "-I$out_root" "-I$src_root"
obja{*} bmia{*}: cxx.poptions += -DLIBBUTL_STATIC_BUILD
@@ -53,6 +62,11 @@ if ($cxx.target.class == "windows")
else
cxx.libs += -lpthread
+#@@ MOD bogus warning if module and dll-exported function called within DLL.
+#
+if ($cxx.features.modules && $cxx.id == 'msvc')
+ cxx.loptions += /ignore:4217
+
# Install into the libbutl/ subdirectory of, say, /usr/include/ recreating
# subdirectories.
#
diff --git a/libbutl/char-scanner.cxx b/libbutl/char-scanner.cxx
index a97ed48..2e680b6 100644
--- a/libbutl/char-scanner.cxx
+++ b/libbutl/char-scanner.cxx
@@ -2,7 +2,33 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/char-scanner.hxx>
+#ifndef __cpp_modules
+#include <libbutl/char-scanner.mxx>
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string> // char_traits
+#include <cstdint> // uint64_t
+#include <istream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.char_scanner;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.fdstream;
+#endif
+
+#endif
using namespace std;
diff --git a/libbutl/char-scanner.hxx b/libbutl/char-scanner.mxx
index 3aa1e0d..af4dad9 100644
--- a/libbutl/char-scanner.hxx
+++ b/libbutl/char-scanner.mxx
@@ -1,19 +1,35 @@
-// file : libbutl/char-scanner.hxx -*- C++ -*-
+// file : libbutl/char-scanner.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_CHAR_SCANNER_HXX
-#define LIBBUTL_CHAR_SCANNER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string> // char_traits
#include <cstdint> // uint64_t
#include <istream>
+#endif
+
+// Other includes.
-#include <libbutl/fdstream.hxx>
+#ifdef __cpp_modules
+export module butl.char_scanner;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.fdstream;
+#else
+#include <libbutl/fdstream.mxx>
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Low-level character stream scanner. Normally used as a base for
// higher-level lexers.
@@ -123,5 +139,3 @@ namespace butl
}
#include <libbutl/char-scanner.ixx>
-
-#endif // LIBBUTL_CHAR_SCANNER_HXX
diff --git a/libbutl/const-ptr.hxx b/libbutl/const-ptr.mxx
index e50704d..a4b86be 100644
--- a/libbutl/const-ptr.hxx
+++ b/libbutl/const-ptr.mxx
@@ -1,13 +1,29 @@
-// file : libbutl/const-ptr.hxx -*- C++ -*-
+// file : libbutl/const-ptr.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_CONST_PTR_HXX
-#define LIBBUTL_CONST_PTR_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <cstddef> // nullptr_t
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.const_ptr;
+#ifdef __cpp_lib_modules
+import std.core; // @@ MOD std.fundamental.
+#endif
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Const-propagating pointer.
//
@@ -76,5 +92,3 @@ namespace butl
T* p_;
};
}
-
-#endif // LIBBUTL_CONST_PTR_HXX
diff --git a/libbutl/curl.cxx b/libbutl/curl.cxx
index a04d52e..5ff81ab 100644
--- a/libbutl/curl.cxx
+++ b/libbutl/curl.cxx
@@ -2,12 +2,39 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/curl.hxx>
+#ifndef __cpp_modules
+#include <libbutl/curl.mxx>
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <utility> // move()
#include <exception> // invalid_argument
-
-#include <libbutl/utility.hxx> // casecmp()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.curl;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.process;
+import butl.fdstream;
+import butl.small_vector;
+#endif
+
+import butl.utility; // casecmp()
+#else
+#include <libbutl/utility.mxx>
+#endif
using namespace std;
diff --git a/libbutl/curl.ixx b/libbutl/curl.ixx
index 204dfa1..0ad3bf5 100644
--- a/libbutl/curl.ixx
+++ b/libbutl/curl.ixx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cstddef> // size_t
-#include <utility> // forward()
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename I,
typename O,
diff --git a/libbutl/curl.hxx b/libbutl/curl.mxx
index dad0bf5..57d6e56 100644
--- a/libbutl/curl.hxx
+++ b/libbutl/curl.mxx
@@ -1,20 +1,43 @@
-// file : libbutl/curl.hxx -*- C++ -*-
+// file : libbutl/curl.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_CURL_HXX
-#define LIBBUTL_CURL_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <type_traits>
-#include <libbutl/export.hxx>
+#include <cstddef> // size_t
+#include <utility> // forward()
+#include <exception> // invalid_argument
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.curl;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.process; //@@ MOD TODO: should we re-export?
+import butl.fdstream;
+import butl.small_vector;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/small-vector.hxx>
+#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Perform a method (GET, POST, PUT) on a URL using the curl(1) program.
// Throw process_error and io_error (both derive from system_error) in case
@@ -170,5 +193,3 @@ namespace butl
#include <libbutl/curl.ixx>
#include <libbutl/curl.txx>
-
-#endif // LIBBUTL_CURL_HXX
diff --git a/libbutl/curl.txx b/libbutl/curl.txx
index 0c5fb2f..9686d0b 100644
--- a/libbutl/curl.txx
+++ b/libbutl/curl.txx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <utility> // forward()
-#include <exception> // invalid_argument
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename I>
typename std::enable_if<curl::is_other<I>::value, I>::type curl::
diff --git a/libbutl/diagnostics.cxx b/libbutl/diagnostics.cxx
index 33d8e3a..6189775 100644
--- a/libbutl/diagnostics.cxx
+++ b/libbutl/diagnostics.cxx
@@ -2,25 +2,52 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/diagnostics.hxx>
+#ifndef __cpp_modules
+#include <libbutl/diagnostics.mxx>
+#endif
#ifndef _WIN32
# include <unistd.h> // write()
#else
# include <libbutl/win32-utility.hxx>
-
# include <io.h> //_write()
#endif
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <utility>
+#include <exception>
+
#include <ios> // ios::failure
#include <mutex>
#include <string>
-#include <cassert>
#include <cstddef> // size_t
#include <iostream> // cerr
+#endif
-#include <libbutl/optional.hxx>
-#include <libbutl/fdstream.hxx> // stderr_fd(), fdterm()
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.diagnostics;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+//@@ MOD TODO: std.threading
+import butl.utility;
+import butl.optional;
+import butl.fdstream; // stderr_fd(), fdterm()
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/optional.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
using namespace std;
diff --git a/libbutl/diagnostics.hxx b/libbutl/diagnostics.mxx
index c1491d6..af74956 100644
--- a/libbutl/diagnostics.hxx
+++ b/libbutl/diagnostics.mxx
@@ -1,21 +1,33 @@
-// file : libbutl/diagnostics.hxx -*- C++ -*-
+// file : libbutl/diagnostics.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_DIAGNOSTICS_HXX
-#define LIBBUTL_DIAGNOSTICS_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <ostream>
#include <sstream>
-#include <utility> // move(), forward()
+#include <utility> // move(), forward()
+#include <exception> // uncaught_exception[s]()
+#endif
+
#include <libbutl/ft/exception.hxx> // uncaught_exceptions
-#include <exception> // uncaught_exception(s)()
+
+#ifdef __cpp_modules
+export module butl.diagnostics;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-#include <libbutl/utility.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Diagnostic facility base infrastructure.
//
@@ -261,5 +273,3 @@ namespace butl
}
};
}
-
-#endif // LIBBUTL_DIAGNOSTICS_HXX
diff --git a/libbutl/export.hxx b/libbutl/export.hxx
index 5c59539..82e06cb 100644
--- a/libbutl/export.hxx
+++ b/libbutl/export.hxx
@@ -2,12 +2,11 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_EXPORT_HXX
-#define LIBBUTL_EXPORT_HXX
+#pragma once
-// If we are compiling a module interface, setup the module export.
+// If modules are available, setup the module export.
//
-#ifdef LIBBUTL_MODULE_BUILD
+#ifdef __cpp_modules
# define LIBBUTL_MODEXPORT export
#else
# define LIBBUTL_MODEXPORT
@@ -45,5 +44,3 @@
//
# define LIBBUTL_SYMEXPORT // Using static or shared.
#endif
-
-#endif // LIBBUTL_EXPORT_HXX
diff --git a/libbutl/fdstream.cxx b/libbutl/fdstream.cxx
index ab78e6a..905c36f 100644
--- a/libbutl/fdstream.cxx
+++ b/libbutl/fdstream.cxx
@@ -2,7 +2,11 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/fdstream.hxx>
+#ifndef __cpp_modules
+#include <libbutl/fdstream.mxx>
+#endif
+
+#include <errno.h> // errno, E*
#ifndef _WIN32
# include <fcntl.h> // open(), O_*, fcntl()
@@ -21,23 +25,46 @@
# include <fcntl.h> // _O_*
# include <sys/stat.h> // S_I*
-# include <cwchar> // wcsncmp(), wcsstr()
+# include <wchar.h> // wcsncmp(), wcsstr()
#endif
-#include <errno.h> // errno, E*
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <vector>
+#include <string>
+#include <istream>
+#include <ostream>
+#include <utility>
+#include <cstdint>
#include <ios> // ios_base::openmode, ios_base::failure
#include <new> // bad_alloc
#include <limits> // numeric_limits
-#include <cassert>
#include <cstring> // memcpy(), memmove()
#include <exception> // uncaught_exception()
#include <stdexcept> // invalid_argument
#include <type_traits>
#include <system_error>
+#endif
#include <libbutl/process-details.hxx>
+#ifdef __cpp_modules
+module butl.fdstream;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.filesystem;
+#endif
+
+#endif
+
using namespace std;
#ifdef _WIN32
diff --git a/libbutl/fdstream.ixx b/libbutl/fdstream.ixx
index 212ec98..5678fba 100644
--- a/libbutl/fdstream.ixx
+++ b/libbutl/fdstream.ixx
@@ -2,9 +2,6 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cassert>
-#include <iterator>
-
namespace butl
{
// auto_fd
diff --git a/libbutl/fdstream.hxx b/libbutl/fdstream.mxx
index 3bd8e8b..f84b88e 100644
--- a/libbutl/fdstream.hxx
+++ b/libbutl/fdstream.mxx
@@ -1,10 +1,14 @@
-// file : libbutl/fdstream.hxx -*- C++ -*-
+// file : libbutl/fdstream.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_FDSTREAM_HXX
-#define LIBBUTL_FDSTREAM_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+#include <cassert>
+#ifndef __cpp_lib_modules
#include <vector>
#include <string>
#include <istream>
@@ -12,12 +16,27 @@
#include <utility> // move()
#include <cstdint> // uint16_t, uint64_t
-#include <libbutl/export.hxx>
+#include <iterator>
+#endif
-#include <libbutl/path.hxx>
-#include <libbutl/filesystem.hxx> // permissions
+// Other includes.
-namespace butl
+#ifdef __cpp_modules
+export module butl.fdstream;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.filesystem; // permissions
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// RAII type for file descriptors. Note that failure to close the descriptor
// is silently ignored by both the destructor and reset().
@@ -26,7 +45,11 @@ namespace butl
// and is not closed.
//
struct nullfd_t {constexpr explicit nullfd_t (int) {}};
- constexpr const nullfd_t nullfd (-1);
+#if defined(__cpp_modules) && defined(__clang__) //@@ MOD Clang duplicate sym.
+ inline constexpr nullfd_t nullfd (-1);
+#else
+ const/*expr*/ nullfd_t nullfd (-1); //@@ MOD VC multiple defs.
+#endif
class LIBBUTL_SYMEXPORT auto_fd
{
@@ -695,5 +718,3 @@ namespace butl
}
#include <libbutl/fdstream.ixx>
-
-#endif // LIBBUTL_FDSTREAM_HXX
diff --git a/libbutl/filesystem.cxx b/libbutl/filesystem.cxx
index 7ba5275..8c3abc4 100644
--- a/libbutl/filesystem.cxx
+++ b/libbutl/filesystem.cxx
@@ -2,7 +2,11 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/filesystem.hxx>
+#ifndef __cpp_modules
+#include <libbutl/filesystem.mxx>
+#endif
+
+#include <errno.h> // errno, E*
#ifndef _WIN32
# include <stdio.h> // rename()
@@ -25,25 +29,46 @@
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
# endif
-
-# include <libbutl/utility.hxx> // lcase()
#endif
-#include <errno.h> // errno, E*
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+#include <iterator>
+#include <functional>
#include <string>
#include <vector>
#include <memory> // unique_ptr
-#include <cstddef> // size_t
-#include <utility> // pair
-#include <iterator> // reverse_iterator
#include <system_error>
+#endif
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // throw_generic_error()
-#include <libbutl/fdstream.hxx>
-#include <libbutl/small-vector.hxx>
+#ifdef __cpp_modules
+module butl.filesystem;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.timestamp;
+#endif
+
+import butl.utility; // throw_generic_error(), lcase()[_WIN32]
+import butl.fdstream;
+import butl.small_vector;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
using namespace std;
diff --git a/libbutl/filesystem.ixx b/libbutl/filesystem.ixx
index a618d5b..170c108 100644
--- a/libbutl/filesystem.ixx
+++ b/libbutl/filesystem.ixx
@@ -2,8 +2,6 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <errno.h> // E*
-
namespace butl
{
inline bool
diff --git a/libbutl/filesystem.hxx b/libbutl/filesystem.mxx
index ef1b22b..271220f 100644
--- a/libbutl/filesystem.hxx
+++ b/libbutl/filesystem.mxx
@@ -1,9 +1,12 @@
-// file : libbutl/filesystem.hxx -*- C++ -*-
+// file : libbutl/filesystem.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_FILESYSTEM_HXX
-#define LIBBUTL_FILESYSTEM_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+#include <errno.h> // E*
#ifndef _WIN32
# include <dirent.h> // DIR
@@ -11,7 +14,7 @@
# include <stddef.h> // intptr_t
#endif
-// VC's sys/types.h header file doesn't define mode_t type. So let's define it
+// VC's sys/types.h header file doesn't define mode_t type. So we define it
// ourselves according to the POSIX specification.
//
#ifndef _MSC_VER
@@ -20,18 +23,38 @@
typedef int mode_t;
#endif
+#ifndef __cpp_lib_modules
#include <cstddef> // ptrdiff_t
#include <cstdint> // uint16_t, etc
#include <utility> // move(), pair
#include <iterator>
#include <functional>
-#include <libbutl/export.hxx>
+#include <chrono> //@@ MOD needed by timestamp module.
+#endif
+
+// Other includes.
+#ifdef __cpp_modules
+export module butl.filesystem;
+
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
-#include <libbutl/path.hxx>
-#include <libbutl/timestamp.hxx>
+import butl.path;
+import butl.timestamp;
-namespace butl
+import butl.utility;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/timestamp.mxx>
+
+#include <libbutl/utility.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Return true if the path is to an existing regular file. Note that by
// default this function follows symlinks.
@@ -622,5 +645,3 @@ namespace butl
}
#include <libbutl/filesystem.ixx>
-
-#endif // LIBBUTL_FILESYSTEM_HXX
diff --git a/libbutl/ft/exception.hxx b/libbutl/ft/exception.hxx
index a5f6156..14d9ced 100644
--- a/libbutl/ft/exception.hxx
+++ b/libbutl/ft/exception.hxx
@@ -5,8 +5,11 @@
#ifndef LIBBUTL_FT_EXCEPTION_HXX
#define LIBBUTL_FT_EXCEPTION_HXX
-#include <cstddef> // _LIBCPP_VERSION
-#include <exception>
+#if defined(__clang__)
+# if __has_include(<__config>)
+# include <__config> // _LIBCPP_VERSION
+# endif
+#endif
// __cpp_lib_uncaught_exceptions
//
diff --git a/libbutl/ft/shared_mutex.hxx b/libbutl/ft/shared_mutex.hxx
index 6c6d415..a0346fc 100644
--- a/libbutl/ft/shared_mutex.hxx
+++ b/libbutl/ft/shared_mutex.hxx
@@ -5,8 +5,11 @@
#ifndef LIBBUTL_FT_SHARED_MUTEX_HXX
#define LIBBUTL_FT_SHARED_MUTEX_HXX
-#include <cstddef> // _LIBCPP_VERSION
-#include <shared_mutex>
+#if defined(__clang__)
+# if __has_include(<__config>)
+# include <__config> // _LIBCPP_VERSION
+# endif
+#endif
// __cpp_lib_shared_mutex
//
diff --git a/libbutl/manifest-forward.hxx b/libbutl/manifest-forward.hxx
index c5aa356..e221fdf 100644
--- a/libbutl/manifest-forward.hxx
+++ b/libbutl/manifest-forward.hxx
@@ -2,8 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_MANIFEST_FORWARD_HXX
-#define LIBBUTL_MANIFEST_FORWARD_HXX
+#pragma once
namespace butl
{
@@ -21,5 +20,3 @@ namespace butl
fail
};
}
-
-#endif // LIBBUTL_MANIFEST_FORWARD_HXX
diff --git a/libbutl/manifest-parser.cxx b/libbutl/manifest-parser.cxx
index 304815a..cea71b6 100644
--- a/libbutl/manifest-parser.cxx
+++ b/libbutl/manifest-parser.cxx
@@ -2,10 +2,36 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/manifest-parser.hxx>
+#ifndef __cpp_modules
+#include <libbutl/manifest-parser.mxx>
+#endif
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstdint>
+#include <utility>
+#include <stdexcept>
+
#include <sstream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.manifest_parser;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.char_scanner;
+#endif
+
+#endif
using namespace std;
@@ -410,7 +436,7 @@ namespace butl
// manifest_parsing
//
- static string
+ static inline string
format (const string& n, uint64_t l, uint64_t c, const string& d)
{
ostringstream os;
diff --git a/libbutl/manifest-parser.hxx b/libbutl/manifest-parser.mxx
index f84badd..c21ccc1 100644
--- a/libbutl/manifest-parser.hxx
+++ b/libbutl/manifest-parser.mxx
@@ -1,21 +1,37 @@
-// file : libbutl/manifest-parser.hxx -*- C++ -*-
+// file : libbutl/manifest-parser.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_MANIFEST_PARSER_HXX
-#define LIBBUTL_MANIFEST_PARSER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <iosfwd>
#include <cstdint> // uint64_t
#include <utility> // pair
#include <stdexcept> // runtime_error
+#endif
-#include <libbutl/export.hxx>
+// Other includes.
-#include <libbutl/char-scanner.hxx>
+#ifdef __cpp_modules
+export module butl.manifest_parser;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.char_scanner;
+#else
+#include <libbutl/char-scanner.mxx>
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
class LIBBUTL_SYMEXPORT manifest_parsing: public std::runtime_error
{
@@ -98,5 +114,3 @@ namespace butl
std::string version_; // Current format version.
};
}
-
-#endif // LIBBUTL_MANIFEST_PARSER_HXX
diff --git a/libbutl/manifest-serializer.cxx b/libbutl/manifest-serializer.cxx
index d8f640b..0693c2e 100644
--- a/libbutl/manifest-serializer.cxx
+++ b/libbutl/manifest-serializer.cxx
@@ -2,11 +2,36 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/manifest-serializer.hxx>
+#ifndef __cpp_modules
+#include <libbutl/manifest-serializer.mxx>
+#endif
-#include <ostream>
#include <cassert>
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstddef>
+#include <stdexcept>
+
+#include <ostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.manifest_serializer;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.char_scanner;
+#endif
+
+#endif
+
using namespace std;
namespace butl
@@ -257,7 +282,7 @@ namespace butl
// manifest_serialization
//
- static string
+ static inline string
format (const string& n, const string& d)
{
string r;
diff --git a/libbutl/manifest-serializer.hxx b/libbutl/manifest-serializer.mxx
index d95ddf1..e468786 100644
--- a/libbutl/manifest-serializer.hxx
+++ b/libbutl/manifest-serializer.mxx
@@ -1,18 +1,33 @@
-// file : libbutl/manifest-serializer.hxx -*- C++ -*-
+// file : libbutl/manifest-serializer.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_MANIFEST_SERIALIZER_HXX
-#define LIBBUTL_MANIFEST_SERIALIZER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <iosfwd>
#include <cstddef> // size_t
#include <stdexcept> // runtime_error
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.manifest_serializer;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
class LIBBUTL_SYMEXPORT manifest_serialization: public std::runtime_error
{
@@ -78,5 +93,3 @@ namespace butl
const std::string name_;
};
}
-
-#endif // LIBBUTL_MANIFEST_SERIALIZER_HXX
diff --git a/libbutl/multi-index.hxx b/libbutl/multi-index.mxx
index 448e1f7..f0ef298 100644
--- a/libbutl/multi-index.hxx
+++ b/libbutl/multi-index.mxx
@@ -1,14 +1,30 @@
-// file : libbutl/multi-index.hxx -*- C++ -*-
+// file : libbutl/multi-index.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_MULTI_INDEX_HXX
-#define LIBBUTL_MULTI_INDEX_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <utility> // declval()
#include <functional> // hash
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.multi_index;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Google the "Emulating Boost.MultiIndex with Standard Containers" blog
// post for details.
@@ -42,7 +58,7 @@ namespace butl
};
}
-namespace std
+LIBBUTL_MODEXPORT namespace std
{
template <typename T>
struct hash<butl::map_key<T>>: hash<T>
@@ -55,5 +71,3 @@ namespace std
}
};
}
-
-#endif // LIBBUTL_MULTI_INDEX_HXX
diff --git a/libbutl/openssl.cxx b/libbutl/openssl.cxx
index aa4e720..89cf8ed 100644
--- a/libbutl/openssl.cxx
+++ b/libbutl/openssl.cxx
@@ -2,9 +2,35 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/openssl.hxx>
+#ifndef __cpp_modules
+#include <libbutl/openssl.mxx>
+#endif
+
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <utility> // move()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.openssl;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.process;
+import butl.fdstream;
+import butl.small_vector;
+#endif
+
+#endif
using namespace std;
diff --git a/libbutl/openssl.ixx b/libbutl/openssl.ixx
index 2976659..3ef56ed 100644
--- a/libbutl/openssl.ixx
+++ b/libbutl/openssl.ixx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cstddef> // size_t
-#include <utility> // move(), forward()
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename I,
typename O,
diff --git a/libbutl/openssl.hxx b/libbutl/openssl.mxx
index 9ab248c..42afc5e 100644
--- a/libbutl/openssl.hxx
+++ b/libbutl/openssl.mxx
@@ -1,20 +1,42 @@
-// file : libbutl/openssl.hxx -*- C++ -*-
+// file : libbutl/openssl.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_OPENSSL_HXX
-#define LIBBUTL_OPENSSL_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <type_traits>
-#include <libbutl/export.hxx>
+#include <cstddef> // size_t
+#include <utility> // move(), forward()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.openssl;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.process; //@@ MOD TODO: should we re-export?
+import butl.fdstream;
+import butl.small_vector;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/small-vector.hxx>
+#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Perform a crypto operation using the openssl(1) program. Throw
// process_error and io_error (both derive from system_error) in case of
@@ -160,5 +182,3 @@ namespace butl
#include <libbutl/openssl.ixx>
#include <libbutl/openssl.txx>
-
-#endif // LIBBUTL_OPENSSL_HXX
diff --git a/libbutl/openssl.txx b/libbutl/openssl.txx
index dd8a470..29dc4b1 100644
--- a/libbutl/openssl.txx
+++ b/libbutl/openssl.txx
@@ -2,9 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <utility> // move(), forward()
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename I>
typename std::enable_if<openssl::is_other<I>::value, I>::type openssl::
diff --git a/libbutl/optional.hxx b/libbutl/optional.mxx
index c1bc582..4478f84 100644
--- a/libbutl/optional.hxx
+++ b/libbutl/optional.mxx
@@ -1,19 +1,38 @@
-// file : libbutl/optional.hxx -*- C++ -*-
+// file : libbutl/optional.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_OPTIONAL_HXX
-#define LIBBUTL_OPTIONAL_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <utility> // move()
#include <functional> // hash
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.optional;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Simple optional class template while waiting for std::optional.
//
struct nullopt_t {constexpr explicit nullopt_t (int) {}};
- constexpr const nullopt_t nullopt (1);
+#if defined(__cpp_modules) && defined(__clang__) //@@ MOD Clang duplicate sym.
+ inline
+#endif
+ const/*expr*/ nullopt_t nullopt (1); //@@ MOD VC multiple defs.
template <typename T>
class optional
@@ -92,5 +111,3 @@ namespace std
}
};
}
-
-#endif // LIBBUTL_OPTIONAL_HXX
diff --git a/libbutl/pager.cxx b/libbutl/pager.cxx
index 3910443..6453120 100644
--- a/libbutl/pager.cxx
+++ b/libbutl/pager.cxx
@@ -2,24 +2,59 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/pager.hxx>
+#ifndef __cpp_modules
+#include <libbutl/pager.mxx>
+#endif
+
+#include <errno.h> // E*
#ifndef _WIN32
# include <unistd.h> // STDOUT_FILENO
# include <sys/ioctl.h> // ioctl()
+#else
+# include <libbutl/win32-utility.hxx>
+#endif
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include <cstring> // strchr()
+#include <utility> // move()
+#ifndef _WIN32
# include <chrono>
# include <thread> // this_thread::sleep_for()
-#else
-# include <libbutl/win32-utility.hxx>
+#endif
#endif
-#include <cstring> // strchr()
-#include <utility> // move()
+// Other includes.
-#include <libbutl/utility.hxx> // operator<<(ostream, exception),
- // throw_generic_error()
-#include <libbutl/fdstream.hxx> // fdclose()
+#ifdef __cpp_modules
+module butl.pager;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.process;
+import butl.fdstream;
+#endif
+
+#ifndef _WIN32
+import std.core; //@@ MOD TODO: import std.threading.
+#endif
+
+import butl.utility; // operator<<(ostream, exception), throw_generic_error()
+import butl.optional;
+import butl.fdstream; // fdclose()
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/optional.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
using namespace std;
diff --git a/libbutl/pager.hxx b/libbutl/pager.mxx
index f167f10..6955f53 100644
--- a/libbutl/pager.hxx
+++ b/libbutl/pager.mxx
@@ -1,20 +1,37 @@
-// file : libbutl/pager.hxx -*- C++ -*-
+// file : libbutl/pager.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PAGER_HXX
-#define LIBBUTL_PAGER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <vector>
#include <iostream>
+#endif
-#include <libbutl/export.hxx>
+// Other includes.
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
+#ifdef __cpp_modules
+export module butl.pager;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.process;
+import butl.fdstream;
+#else
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Try to run the output through a pager program, such as more or less (no
// pun intended, less is used by default). If the default pager program is
@@ -84,5 +101,3 @@ namespace butl
std::streambuf* buf_ = nullptr;
};
}
-
-#endif // LIBBUTL_PAGER_HXX
diff --git a/libbutl/path-io.hxx b/libbutl/path-io.mxx
index 719456d..ae1ee84 100644
--- a/libbutl/path-io.hxx
+++ b/libbutl/path-io.mxx
@@ -1,15 +1,33 @@
-// file : libbutl/path-io.hxx -*- C++ -*-
+// file : libbutl/path-io.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PATH_IO_HXX
-#define LIBBUTL_PATH_IO_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <ostream>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
+#ifdef __cpp_modules
+export module butl.path_io;
+#ifdef __cpp_lib_modules
+import std.core; //@@ MOD TMP (should not be needed).
+import std.io;
+#endif
+import butl.path;
+#else
+#include <libbutl/path.mxx>
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// This is the default path IO implementation. The reason it is
// separate is because one often wants a custom implementation.
@@ -25,5 +43,3 @@ namespace butl
return os << p.string ();
}
}
-
-#endif // LIBBUTL_PATH_IO_HXX
diff --git a/libbutl/path-map.hxx b/libbutl/path-map.mxx
index fa06bd5..c526a89 100644
--- a/libbutl/path-map.hxx
+++ b/libbutl/path-map.mxx
@@ -1,16 +1,34 @@
-// file : libbutl/path-map.hxx -*- C++ -*-
+// file : libbutl/path-map.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PATH_MAP_HXX
-#define LIBBUTL_PATH_MAP_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <algorithm> // min()
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/prefix-map.hxx>
+#ifdef __cpp_modules
+export module butl.path_map;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.prefix_map;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/prefix-map.mxx>
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// prefix_map for filesystem paths
//
@@ -144,5 +162,3 @@ namespace butl
template <typename T>
using dir_path_map = path_map_impl<dir_path, T>;
}
-
-#endif // LIBBUTL_PATH_MAP_HXX
diff --git a/libbutl/path.cxx b/libbutl/path.cxx
index c1ede40..bbc4754 100644
--- a/libbutl/path.cxx
+++ b/libbutl/path.cxx
@@ -2,7 +2,9 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/path.hxx>
+#ifndef __cpp_modules
+#include <libbutl/path.mxx>
+#endif
#ifdef _WIN32
# include <libbutl/win32-utility.hxx>
@@ -21,18 +23,37 @@
# include <string.h> // strlen(), strcpy()
# include <sys/stat.h> // stat(), S_IS*
# include <sys/types.h> // stat
-
-# include <vector>
#endif
-#include <atomic>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstddef>
+#include <utility>
+
+#include <atomic>
#include <cstring> // strcpy()
+#endif
-#include <libbutl/export.hxx>
+#ifdef __cpp_modules
+module butl.path;
-#include <libbutl/utility.hxx> // throw_*_error()
-#include <libbutl/process.hxx>
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
+
+import butl.utility; // throw_*_error()
+import butl.process; // process::current_id()
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/process.mxx>
+#endif
+
+#include <libbutl/export.hxx>
#ifndef _WIN32
# ifndef PATH_MAX
@@ -88,9 +109,11 @@ namespace butl
// one of the drive requires the trailing directory separator to be
// present.
//
- string_type const& d (!root (s)
- ? s
- : string_type (s + directory_separator));
+ string_type const& d (
+ !root (s)
+ ? s
+ //@@ MOD VC ADL does not seem to kick in for some reason...
+ : string_type (std::operator+ (s, directory_separator)));
if (_chdir (d.c_str ()) != 0)
throw_generic_error (errno);
@@ -168,7 +191,7 @@ namespace butl
#endif
}
- static atomic<size_t> temp_name_count;
+ static atomic<size_t> temp_name_count (0);
template <>
LIBBUTL_SYMEXPORT path_traits<char>::string_type path_traits<char>::
diff --git a/libbutl/path.ixx b/libbutl/path.ixx
index 7227b72..f983f5d 100644
--- a/libbutl/path.ixx
+++ b/libbutl/path.ixx
@@ -2,39 +2,25 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifdef _WIN32
-# include <cwctype> // towlower(), towupper()
-#endif
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
#ifdef _WIN32
template <>
+ LIBBUTL_SYMEXPORT //@@ MOD VC needs it for some reason.
inline char path_traits<char>::
tolower (char c)
{
- return lcase (c);
- }
-
- template <>
- inline wchar_t path_traits<wchar_t>::
- tolower (wchar_t c)
- {
- return std::towlower (c);
+ //@@ MOD VC-ICE return lcase (c);
+ return std::tolower (c);
}
template <>
+ LIBBUTL_SYMEXPORT //@@ MOD VC needs it for some reason.
inline char path_traits<char>::
toupper (char c)
{
- return ucase (c);
- }
-
- template <>
- inline wchar_t path_traits<wchar_t>::
- toupper (wchar_t c)
- {
- return std::towupper (c);
+ //@@ MOD VC-ICE return ucase (c);
+ return std::toupper (c);
}
#endif
diff --git a/libbutl/path.hxx b/libbutl/path.mxx
index 69e0428..31101fc 100644
--- a/libbutl/path.hxx
+++ b/libbutl/path.mxx
@@ -1,10 +1,14 @@
-// file : libbutl/path.hxx -*- C++ -*-
+// file : libbutl/path.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PATH_HXX
-#define LIBBUTL_PATH_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+#include <cassert>
+#ifndef __cpp_lib_modules
#include <string>
#include <cstddef> // ptrdiff_t
#include <utility> // move(), swap()
@@ -12,11 +16,32 @@
#include <exception>
#include <functional> // hash
-#include <libbutl/export.hxx>
+#include <vector>
+#ifdef _WIN32
+#include <cctype> // toupper/lower() @@ MOD TMP
+#include <algorithm> // replace()
+#endif
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.path;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#ifdef _WIN32
+import butl.utility;
+#endif
+#else
+#ifdef _WIN32
+#include <libbutl/utility.mxx> // *case*()
+#endif
+#endif
-#include <libbutl/utility.hxx>
+#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Wish list/ideas for improvements.
//
@@ -510,10 +535,11 @@ namespace butl
}
};
+
template <typename C>
struct any_path_kind
{
- class base_type: protected path_data<C> // In essence protected path_data.
+ class base_type: public path_data<C> // In essence protected path_data.
{
protected:
using path_data<C>::path_data;
@@ -522,6 +548,8 @@ namespace butl
base_type (path_data<C>&& d): path_data<C> (std::move (d)) {}
};
+ //using base_type = path_data<C>; // @@ MOD VC-ICE
+
using dir_type = basic_path<C, dir_path_kind<C>>;
// Init and cast.
@@ -562,6 +590,8 @@ namespace butl
cast (data_type&);
};
+ struct exact_path_type {}; //@@ MOD TMP
+
template <typename C, typename K>
class basic_path: public K::base_type
{
@@ -608,8 +638,9 @@ namespace butl
// untouched. Note that no exception is thrown if the path is invalid. See
// also representation()&& below.
//
- enum exact_type {exact};
- basic_path (string_type&& s, exact_type)
+ //@@ MOD VC-ICE enum exact_type {exact};
+ static const exact_path_type exact;
+ basic_path (string_type&& s, exact_path_type)
: base_type (K::init (std::move (s), true)) {}
// Create a path as a sub-path identified by the [begin, end) range of
@@ -1053,7 +1084,9 @@ namespace butl
explicit
basic_path (data_type&& d): base_type (std::move (d)) {}
+ #ifndef _MSC_VER //@@ MOD VC ICE
using base_type::_size;
+ #endif
// Common implementation for operator/= and operator+=.
//
@@ -1173,7 +1206,7 @@ namespace butl
// For operator<< (ostream) see the path-io header.
}
-namespace std
+LIBBUTL_MODEXPORT namespace std
{
template <typename C, typename K>
struct hash<butl::basic_path<C, K>>: hash<basic_string<C>>
@@ -1210,5 +1243,3 @@ namespace std
#include <libbutl/path.ixx>
#include <libbutl/path.txx>
-
-#endif // LIBBUTL_PATH_HXX
diff --git a/libbutl/path.txx b/libbutl/path.txx
index 17673f8..512e849 100644
--- a/libbutl/path.txx
+++ b/libbutl/path.txx
@@ -2,14 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <vector>
-#include <cassert>
-
-#ifdef _WIN32
-# include <algorithm> // replace()
-#endif
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename C, typename K>
basic_path<C, K> basic_path<C, K>::
@@ -138,6 +131,7 @@ namespace butl
// Throw system_error in case of other failures. Result and dir can be the
// same instance.
//
+ LIBBUTL_MODEXPORT //@@ MOD VC doesn't "see" it in impl unit unless exported.
template <typename C>
bool
basic_path_append_actual_name (std::basic_string<C>& result,
diff --git a/libbutl/prefix-map.hxx b/libbutl/prefix-map.mxx
index 0404f72..95a4f3b 100644
--- a/libbutl/prefix-map.hxx
+++ b/libbutl/prefix-map.mxx
@@ -1,16 +1,32 @@
-// file : libbutl/prefix-map.hxx -*- C++ -*-
+// file : libbutl/prefix-map.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PREFIX_MAP_HXX
-#define LIBBUTL_PREFIX_MAP_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <map>
#include <string>
#include <utility> // move()
#include <algorithm> // min()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.prefix_map;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// A map of hierarchical "paths", e.g., 'foo.bar' or 'foo/bar' with
// the ability to retrieve a range of entries that have a specific
@@ -134,5 +150,3 @@ namespace butl
}
#include <libbutl/prefix-map.txx>
-
-#endif // LIBBUTL_PREFIX_MAP_HXX
diff --git a/libbutl/prefix-map.txx b/libbutl/prefix-map.txx
index f3cd29f..efcee88 100644
--- a/libbutl/prefix-map.txx
+++ b/libbutl/prefix-map.txx
@@ -2,7 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename M>
auto prefix_map_common<M>::
diff --git a/libbutl/process-details.hxx b/libbutl/process-details.hxx
index b078cbb..adb33fd 100644
--- a/libbutl/process-details.hxx
+++ b/libbutl/process-details.hxx
@@ -2,15 +2,18 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PROCESS_DETAILS_HXX
-#define LIBBUTL_PROCESS_DETAILS_HXX
-
-#include <mutex>
+#pragma once
#include <libbutl/ft/shared_mutex.hxx>
+
+#ifdef __cpp_lib_modules
+import std.core; //@@ MOD std.threading
+#else
+#include <mutex>
#if defined(__cpp_lib_shared_mutex) || defined(__cpp_lib_shared_timed_mutex)
# include <shared_mutex>
#endif
+#endif
namespace butl
{
@@ -45,5 +48,3 @@ namespace butl
//
extern shared_mutex process_spawn_mutex;
}
-
-#endif // LIBBUTL_PROCESS_DETAILS_HXX
diff --git a/libbutl/process-io.hxx b/libbutl/process-io.hxx
deleted file mode 100644
index b70080c..0000000
--- a/libbutl/process-io.hxx
+++ /dev/null
@@ -1,28 +0,0 @@
-// file : libbutl/process-io.hxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef LIBBUTL_PROCESS_IO_HXX
-#define LIBBUTL_PROCESS_IO_HXX
-
-#include <ostream>
-
-#include <libbutl/process.hxx>
-
-namespace butl
-{
- inline std::ostream&
- operator<< (std::ostream& o, const process_path& p)
- {
- return o << p.recall_string ();
- }
-
- inline std::ostream&
- operator<< (std::ostream& o, const process_args& a)
- {
- process::print (o, a.argv, a.argc);
- return o;
- }
-}
-
-#endif // LIBBUTL_PROCESS_IO_HXX
diff --git a/libbutl/process-io.mxx b/libbutl/process-io.mxx
new file mode 100644
index 0000000..dfd2221
--- /dev/null
+++ b/libbutl/process-io.mxx
@@ -0,0 +1,44 @@
+// file : libbutl/process-io.mxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <ostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.process_io;
+#ifdef __cpp_lib_modules
+import std.core; //@@ MOD TMP (should not be needed).
+import std.io;
+#endif
+import butl.process;
+#else
+#include <libbutl/process.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
+{
+ inline std::ostream&
+ operator<< (std::ostream& o, const process_path& p)
+ {
+ return o << p.recall_string ();
+ }
+
+ inline std::ostream&
+ operator<< (std::ostream& o, const process_args& a)
+ {
+ process::print (o, a.argv, a.argc);
+ return o;
+ }
+}
diff --git a/libbutl/process-run.cxx b/libbutl/process-run.cxx
index 9c857d0..fd8abe3 100644
--- a/libbutl/process-run.cxx
+++ b/libbutl/process-run.cxx
@@ -2,10 +2,35 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/process.hxx>
+#ifndef __cpp_modules
+#include <libbutl/process.mxx>
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <cstdlib> // exit()
#include <iostream> // cerr
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.process;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+#endif
+
+import butl.utility; // operator<<(ostream,exception)
+#else
+#include <libbutl/utility.mxx>
+#endif
using namespace std;
diff --git a/libbutl/process-run.txx b/libbutl/process-run.txx
index a9c7e8b..d8d4cb7 100644
--- a/libbutl/process-run.txx
+++ b/libbutl/process-run.txx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cassert>
-#include <utility> // forward(), index_sequence
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename V>
process_env::
diff --git a/libbutl/process.cxx b/libbutl/process.cxx
index dce8d6b..e65018a 100644
--- a/libbutl/process.cxx
+++ b/libbutl/process.cxx
@@ -2,7 +2,11 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/process.hxx>
+#ifndef __cpp_modules
+#include <libbutl/process.mxx>
+#endif
+
+#include <errno.h>
#ifndef _WIN32
# include <stdlib.h> // setenv(), unsetenv()
@@ -27,8 +31,7 @@
# include <stdlib.h> // _MAX_PATH
# include <sys/types.h> // stat
# include <sys/stat.h> // stat(), S_IS*
-# include <processenv.h> // GetEnvironmentStringsA(),
- // FreeEnvironmentStringsA()
+# include <processenv.h> // {Get,Free}EnvironmentStringsA()
# ifdef _MSC_VER // Unlikely to be fixed in newer versions.
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
@@ -37,29 +40,66 @@
# define STDOUT_FILENO 1
# define STDERR_FILENO 2
# endif // _MSC_VER
-
-# include <map>
-# include <chrono>
-# include <cstdlib> // getenv(), __argv[]
-
-# include <libbutl/timestamp.hxx>
-# include <libbutl/small-vector.hxx>
#endif
-#include <errno.h>
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <cstdint>
+#include <cstddef>
+#include <system_error>
#include <ios> // ios_base::failure
-#include <cassert>
-#include <cstddef> // size_t
#include <cstring> // strlen(), strchr()
#include <utility> // move()
#include <ostream>
-#include <libbutl/utility.hxx> // casecmp()
-#include <libbutl/fdstream.hxx> // fdnull()
+#ifdef _WIN32
+#include <map>
+#include <chrono>
+#include <cstdlib> // getenv(), __argv[]
+#endif
+#endif
+
#include <libbutl/process-details.hxx>
-#include <iostream>
+namespace butl
+{
+ shared_mutex process_spawn_mutex; // Out of module purview.
+}
+
+#ifdef __cpp_modules
+module butl.process;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.optional;
+import butl.fdstream;
+import butl.vector_view;
+import butl.small_vector;
+#endif
+
+import butl.utility; // casecmp()
+import butl.fdstream; // fdnull()
+#ifdef _WIN32
+import butl.timestamp;
+#endif
+
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/fdstream.mxx>
+
+#ifdef _WIN32
+#include <libbutl/timestamp.mxx>
+#endif
+#endif
using namespace std;
@@ -69,8 +109,6 @@ using namespace butl::win32;
namespace butl
{
- shared_mutex process_spawn_mutex;
-
// process
//
static process_path
diff --git a/libbutl/process.ixx b/libbutl/process.ixx
index 1f1a2f4..c355855 100644
--- a/libbutl/process.ixx
+++ b/libbutl/process.ixx
@@ -2,8 +2,6 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <utility> // move()
-
namespace butl
{
// process_path
@@ -35,14 +33,21 @@ namespace butl
inline process_path& process_path::
operator= (process_path&& p)
{
+
if (this != &p)
{
if (args0_ != nullptr)
*args0_ = initial;
initial = p.initial;
+
+#if defined(__cpp_modules) && defined(__clang__) //@@ MOD Clang ICE
+ recall = p.recall;
+ effect = p.effect;
+#else
recall = std::move (p.recall);
effect = std::move (p.effect);
+#endif
args0_ = p.args0_;
p.args0_ = nullptr;
diff --git a/libbutl/process.hxx b/libbutl/process.mxx
index 3e1a990..abf7d35 100644
--- a/libbutl/process.hxx
+++ b/libbutl/process.mxx
@@ -1,29 +1,52 @@
-// file : libbutl/process.hxx -*- C++ -*-
+// file : libbutl/process.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_PROCESS_HXX
-#define LIBBUTL_PROCESS_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
#ifndef _WIN32
# include <sys/types.h> // pid_t
#endif
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <string>
#include <vector>
#include <iosfwd>
-#include <cassert>
+#include <cstddef> // size_t
#include <cstdint> // uint32_t
#include <system_error>
-#include <libbutl/path.hxx>
+#include <utility> // move(), forward(), index_sequence
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.process;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.optional;
+import butl.fdstream; // auto_fd, fdpipe
+import butl.vector_view;
+import butl.small_vector;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/optional.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/vector-view.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
+
#include <libbutl/export.hxx>
-#include <libbutl/optional.hxx>
-#include <libbutl/fdstream.hxx> // auto_fd, fdpipe
-#include <libbutl/vector-view.hxx>
-#include <libbutl/small-vector.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
struct process_error: std::system_error
{
@@ -643,7 +666,4 @@ namespace butl
}
#include <libbutl/process.ixx>
-
#include <libbutl/process-run.txx>
-
-#endif // LIBBUTL_PROCESS_HXX
diff --git a/libbutl/regex.cxx b/libbutl/regex.cxx
index a177a74..1da325b 100644
--- a/libbutl/regex.cxx
+++ b/libbutl/regex.cxx
@@ -2,17 +2,42 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/regex.hxx>
-
-#if defined(_MSC_VER) && _MSC_VER <= 1911
-# include <cstring> // strstr()
+#ifndef __cpp_modules
+#include <libbutl/regex.mxx>
#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <regex>
+#include <string>
+
#include <ostream>
#include <sstream>
#include <stdexcept> // runtime_error
+#if defined(_MSC_VER) && _MSC_VER <= 1911
+# include <cstring> // strstr()
+#endif
+#endif
+
+// Other includes.
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
+#ifdef __cpp_modules
+module butl.regex;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+//@@ MOD TODO import std.regex;
+#endif
+#endif
+
+import butl.utility; // operator<<(ostream, exception)
+#else
+#include <libbutl/utility.mxx>
+#endif
namespace std
{
diff --git a/libbutl/regex.ixx b/libbutl/regex.ixx
index dd3ad1d..f0dd687 100644
--- a/libbutl/regex.ixx
+++ b/libbutl/regex.ixx
@@ -2,9 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <utility> // move(), make_pair()
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename C>
inline std::pair<std::basic_string<C>, bool>
diff --git a/libbutl/regex.hxx b/libbutl/regex.mxx
index 2105f05..ca677a5 100644
--- a/libbutl/regex.hxx
+++ b/libbutl/regex.mxx
@@ -1,18 +1,42 @@
-// file : libbutl/regex.hxx -*- C++ -*-
+// file : libbutl/regex.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_REGEX_HXX
-#define LIBBUTL_REGEX_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <regex>
#include <iosfwd>
-#include <string> // basic_string
+#include <string>
#include <utility> // pair
+#include <locale>
+#include <cstddef> // size_t
+#include <utility> // move(), make_pair()
+#endif
+
+#if defined(__clang__) && __has_include(<__config>)
+# include <__config> // _LIBCPP_VERSION
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.regex;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+//@@ MOD TODO import std.regex;
+#endif
+#endif
+
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// Call specified append() function for non-matched substrings and matched
// substring replacements returning true if search succeeded. The function
@@ -61,7 +85,7 @@ namespace butl
std::regex_constants::match_default);
}
-namespace std
+LIBBUTL_MODEXPORT namespace std
{
// Print regex error description but only if it is meaningful (this is also
// why we have to print leading colon).
@@ -72,5 +96,3 @@ namespace std
#include <libbutl/regex.ixx>
#include <libbutl/regex.txx>
-
-#endif // LIBBUTL_REGEX_HXX
diff --git a/libbutl/regex.txx b/libbutl/regex.txx
index dd1a539..d1daa44 100644
--- a/libbutl/regex.txx
+++ b/libbutl/regex.txx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <locale>
-#include <cstddef> // size_t, _LIBCPP_VERSION
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename C, typename F>
bool
diff --git a/libbutl/sendmail.cxx b/libbutl/sendmail.cxx
index abdea32..cd6ddff 100644
--- a/libbutl/sendmail.cxx
+++ b/libbutl/sendmail.cxx
@@ -2,7 +2,32 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/sendmail.hxx>
+#ifndef __cpp_modules
+#include <libbutl/sendmail.mxx>
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.sendmail;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.process;
+import butl.fdstream;
+import butl.small_vector;
+#endif
+
+#endif
using namespace std;
diff --git a/libbutl/sendmail.ixx b/libbutl/sendmail.ixx
index 36c0530..942b9a8 100644
--- a/libbutl/sendmail.ixx
+++ b/libbutl/sendmail.ixx
@@ -2,10 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cstddef> // size_t
-#include <utility> // move(), forward()
-
-namespace butl
+LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
template <typename E, typename... O>
inline sendmail::
diff --git a/libbutl/sendmail.hxx b/libbutl/sendmail.mxx
index c631f18..778ff05 100644
--- a/libbutl/sendmail.hxx
+++ b/libbutl/sendmail.mxx
@@ -1,19 +1,39 @@
-// file : libbutl/sendmail.hxx -*- C++ -*-
+// file : libbutl/sendmail.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_SENDMAIL_HXX
-#define LIBBUTL_SENDMAIL_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
-#include <libbutl/export.hxx>
+#include <cstddef> // size_t
+#include <utility> // move(), forward()
+#endif
+
+// Other includes.
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/small-vector.hxx>
+#ifdef __cpp_modules
+export module butl.sendmail;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.process;
+import butl.fdstream;
+import butl.small_vector;
+#else
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// Send email using the sendmail(1) program.
//
@@ -116,5 +136,3 @@ namespace butl
}
#include <libbutl/sendmail.ixx>
-
-#endif // LIBBUTL_SENDMAIL_HXX
diff --git a/libbutl/sha256.cxx b/libbutl/sha256.cxx
index 09f6844..b0b7301 100644
--- a/libbutl/sha256.cxx
+++ b/libbutl/sha256.cxx
@@ -2,19 +2,21 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/sha256.hxx>
+#ifndef __cpp_modules
+#include <libbutl/sha256.mxx>
+#endif
// C interface for sha256c.
//
#include <stdint.h>
#include <stddef.h> // size_t
-#include <cctype> // isxdigit()
-#include <stdexcept> // invalid_argument
-
-#include <libbutl/utility.hxx> // ucase(), lcase()
-
-using SHA256_CTX = butl::sha256::context;
+struct SHA256_CTX
+{
+ uint32_t state[8];
+ uint64_t count;
+ uint8_t buf[64];
+};
extern "C"
{
@@ -25,23 +27,48 @@ extern "C"
#include "sha256c.c"
}
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstddef>
+#include <cstdint>
+
+#include <cctype> // isxdigit(), toupper(), tolower()
+#include <stdexcept> // invalid_argument
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.sha256;
+
+// Only imports additional to interface.
+#ifdef __cpp_lib_modules
+import std.io;
+#endif
+
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
+
+#endif
+
using namespace std;
namespace butl
{
- // sha256
- //
sha256::
sha256 ()
: done_ (false)
{
- SHA256_Init (&ctx_);
+ SHA256_Init (reinterpret_cast<SHA256_CTX*> (buf_));
}
void sha256::
append (const void* b, size_t n)
{
- SHA256_Update (&ctx_, b, n);
+ SHA256_Update (reinterpret_cast<SHA256_CTX*> (buf_), b, n);
}
const sha256::digest_type& sha256::
@@ -49,9 +76,9 @@ namespace butl
{
if (!done_)
{
- SHA256_Final (bin_, &ctx_);
+ SHA256_Final (bin_, reinterpret_cast<SHA256_CTX*> (buf_));
done_ = true;
- str_[0] = '\0'; // Indicate we haven't computed the string yet.
+ buf_[0] = '\0'; // Indicate we haven't computed the string yet.
}
return bin_;
@@ -67,22 +94,20 @@ namespace butl
if (!done_)
binary ();
- if (str_[0] == '\0')
+ if (buf_[0] == '\0')
{
for (size_t i (0); i != 32; ++i)
{
- str_[i * 2] = hex_map[bin_[i] >> 4];
- str_[i * 2 + 1] = hex_map[bin_[i] & 0x0f];
+ buf_[i * 2] = hex_map[bin_[i] >> 4];
+ buf_[i * 2 + 1] = hex_map[bin_[i] & 0x0f];
}
- str_[64] = '\0';
+ buf_[64] = '\0';
}
- return str_;
+ return buf_;
}
- // Conversion functions
- //
string
sha256_to_fingerprint (const string& s)
{
@@ -103,7 +128,7 @@ namespace butl
if (i > 0 && i % 2 == 0)
f += ":";
- f += ucase (c);
+ f += toupper (c); //@@ MOD revert to ucase()
}
return f;
@@ -133,7 +158,7 @@ namespace butl
if (!isxdigit (c))
bad ();
- s += lcase (c);
+ s += tolower (c); //@@ MOD revert to lcase()
}
}
diff --git a/libbutl/sha256.hxx b/libbutl/sha256.mxx
index 459b46c..c5e5864 100644
--- a/libbutl/sha256.hxx
+++ b/libbutl/sha256.mxx
@@ -1,19 +1,33 @@
-// file : libbutl/sha256.hxx -*- C++ -*-
+// file : libbutl/sha256.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_SHA256_HXX
-#define LIBBUTL_SHA256_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
-#include <cstring> // strlen(), memcpy()
-#include <cstdint>
#include <cstddef> // size_t
+#include <cstdint>
+#include <cstring> // strlen(), memcpy()
#include <type_traits> // enable_if, is_integral
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.sha256;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// SHA256 checksum calculator.
//
@@ -97,19 +111,18 @@ namespace butl
const char*
string () const;
- public:
- struct context
+ private:
+ struct context // Note: identical to SHA256_CTX.
{
- std::uint32_t state[8];
- std::uint64_t count;
- std::uint8_t buf[64];
+ uint32_t state[8];
+ uint64_t count;
+ uint8_t buf[64];
};
- private:
union
{
mutable context ctx_;
- mutable char str_[65];
+ mutable char buf_[sizeof (context)]; // Also used to store string rep.
};
mutable digest_type bin_;
@@ -131,5 +144,3 @@ namespace butl
LIBBUTL_SYMEXPORT std::string
fingerprint_to_sha256 (const std::string&);
}
-
-#endif // LIBBUTL_SHA256_HXX
diff --git a/libbutl/small-vector.hxx b/libbutl/small-vector.mxx
index 84c25e8..ca44ed7 100644
--- a/libbutl/small-vector.hxx
+++ b/libbutl/small-vector.mxx
@@ -1,17 +1,32 @@
-// file : libbutl/small-vector.hxx -*- C++ -*-
+// file : libbutl/small-vector.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_SMALL_VECTOR_HXX
-#define LIBBUTL_SMALL_VECTOR_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
-#include <vector>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <vector>
#include <cstddef> // size_t
-#include <utility> // more(), forward()
+#include <utility> // move(), forward()
#include <type_traits> // true_type
+#endif
+
+// Other includes.
-namespace butl
+#ifdef __cpp_modules
+export module butl.small_vector;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
template <typename T, std::size_t N>
struct small_vector_buffer
@@ -293,5 +308,3 @@ namespace butl
}
};
}
-
-#endif // LIBBUTL_SMALL_VECTOR_HXX
diff --git a/libbutl/standard-version.cxx b/libbutl/standard-version.cxx
index 13d3987..d8582dd 100644
--- a/libbutl/standard-version.cxx
+++ b/libbutl/standard-version.cxx
@@ -2,15 +2,41 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/standard-version.hxx>
+#ifndef __cpp_modules
+#include <libbutl/standard-version.mxx>
+#endif
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <cstdint>
+#include <cstddef>
+#include <ostream>
+
#include <cstdlib> // strtoull()
-#include <cstddef> // size_t
#include <utility> // move()
#include <stdexcept> // invalid_argument
-
-#include <libbutl/utility.hxx> // alnum()
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.standard_version;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.optional;
+#endif
+
+import butl.utility;
+#else
+#include <libbutl/utility.mxx> // alnum()
+#endif
using namespace std;
diff --git a/libbutl/standard-version.hxx b/libbutl/standard-version.mxx
index ebb3994..5082d16 100644
--- a/libbutl/standard-version.hxx
+++ b/libbutl/standard-version.mxx
@@ -1,18 +1,34 @@
-// file : libbutl/standard-version.hxx -*- C++ -*-
+// file : libbutl/standard-version.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_STANDARD_VERSION_HXX
-#define LIBBUTL_STANDARD_VERSION_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+// C includes.
+#ifndef __cpp_lib_modules
#include <string>
#include <cstdint> // uint*_t
#include <cstddef> // size_t
#include <ostream>
+#endif
-#include <libbutl/export.hxx>
+// Other includes.
-#include <libbutl/optional.hxx>
+#ifdef __cpp_modules
+export module butl.standard_version;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.optional;
+#else
+#include <libbutl/optional.mxx>
+#endif
+
+#include <libbutl/export.hxx>
// FreeBSD defines these macros in its <sys/types.h>.
//
@@ -24,7 +40,7 @@
# undef minor
#endif
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// The build2 "standard version" (specific, earliest and stub):
//
@@ -263,5 +279,3 @@ namespace butl
}
#include <libbutl/standard-version.ixx>
-
-#endif // LIBBUTL_STANDARD_VERSION_HXX
diff --git a/libbutl/string-parser.cxx b/libbutl/string-parser.cxx
index c579db0..53c1d1a 100644
--- a/libbutl/string-parser.cxx
+++ b/libbutl/string-parser.cxx
@@ -2,131 +2,156 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/string-parser.hxx>
+#ifndef __cpp_modules
+#include <libbutl/string-parser.mxx>
+#endif
-#include <utility> // move()
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <cstddef>
+#include <utility> // move()
+#include <stdexcept>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.string_parser;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
+
+#endif
using namespace std;
namespace butl
{
- // Utility functions
- //
- inline static bool
- space (char c) noexcept
- {
- return c == ' ' || c == '\t';
- }
-
- // string_parser
- //
- vector<pair<string, size_t>> string_parser::
- parse_quoted_position (const string& s, bool unquote)
+ namespace string_parser
{
- vector<pair<string, size_t>> r;
- for (auto b (s.begin ()), i (b), e (s.end ()); i != e; )
+ // Utility functions.
+ //
+ inline static bool
+ space (char c) noexcept
{
- for (; i != e && space (*i); ++i) ; // Skip spaces.
+ return c == ' ' || c == '\t';
+ }
- if (i == e) // No more strings.
- break;
+ vector<pair<string, size_t>>
+ parse_quoted_position (const string& s, bool unquote)
+ {
+ vector<pair<string, size_t>> r;
+ for (auto b (s.begin ()), i (b), e (s.end ()); i != e; )
+ {
+ for (; i != e && space (*i); ++i) ; // Skip spaces.
- string s;
- char quoting ('\0'); // Current quoting mode, can be used as bool.
- size_t pos (i - b); // String position.
+ if (i == e) // No more strings.
+ break;
- for (; i != e; ++i)
- {
- char c (*i);
+ string s;
+ char quoting ('\0'); // Current quoting mode, can be used as bool.
+ size_t pos (i - b); // String position.
- if (!quoting)
+ for (; i != e; ++i)
{
- if (space (c)) // End of string.
- break;
+ char c (*i);
- if (c == '"' || c == '\'') // Begin of quoted substring.
+ if (!quoting)
{
- quoting = c;
+ if (space (c)) // End of string.
+ break;
+
+ if (c == '"' || c == '\'') // Begin of quoted substring.
+ {
+ quoting = c;
+
+ if (!unquote)
+ s += c;
+
+ continue;
+ }
+ }
+ else if (c == quoting) // End of quoted substring.
+ {
+ quoting = '\0';
if (!unquote)
s += c;
continue;
}
- }
- else if (c == quoting) // End of quoted substring.
- {
- quoting = '\0';
-
- if (!unquote)
- s += c;
- continue;
+ s += c;
}
- s += c;
- }
+ if (quoting)
+ throw invalid_string (i - b, "unterminated quoted string");
- if (quoting)
- throw invalid_string (i - b, "unterminated quoted string");
+ r.emplace_back (move (s), pos);
+ }
- r.emplace_back (move (s), pos);
+ return r;
}
- return r;
- }
-
- vector<string> string_parser::
- parse_quoted (const string& s, bool unquote)
- {
- vector<pair<string, size_t>> sp (parse_quoted_position (s, unquote));
-
- vector<string> r;
- r.reserve (sp.size ());
- for (auto& s: sp)
- r.emplace_back (move (s.first));
+ vector<string>
+ parse_quoted (const string& s, bool unquote)
+ {
+ vector<pair<string, size_t>> sp (parse_quoted_position (s, unquote));
- return r;
- }
+ vector<string> r;
+ r.reserve (sp.size ());
+ for (auto& s: sp)
+ r.emplace_back (move (s.first));
- string string_parser::
- unquote (const string& s)
- {
- string r;
- char quoting ('\0'); // Current quoting mode, can be used as bool.
+ return r;
+ }
- for (auto i (s.begin ()), e (s.end ()); i != e; ++i)
+ string
+ unquote (const string& s)
{
- char c (*i);
+ string r;
+ char quoting ('\0'); // Current quoting mode, can be used as bool.
- if (!quoting)
+ for (auto i (s.begin ()), e (s.end ()); i != e; ++i)
{
- if (c == '"' || c == '\'') // Begin of quoted substring.
+ char c (*i);
+
+ if (!quoting)
{
- quoting = c;
+ if (c == '"' || c == '\'') // Begin of quoted substring.
+ {
+ quoting = c;
+ continue;
+ }
+ }
+ else if (c == quoting) // End of quoted substring.
+ {
+ quoting = '\0';
continue;
}
- }
- else if (c == quoting) // End of quoted substring.
- {
- quoting = '\0';
- continue;
+
+ r += c;
}
- r += c;
+ return r;
}
- return r;
- }
-
- vector<string> string_parser::
- unquote (const vector<string>& v)
- {
- vector<string> r;
- r.reserve (v.size ());
- for (auto& s: v)
- r.emplace_back (unquote (s));
+ vector<string>
+ unquote (const vector<string>& v)
+ {
+ vector<string> r;
+ r.reserve (v.size ());
+ for (auto& s: v)
+ r.emplace_back (unquote (s));
- return r;
+ return r;
+ }
}
}
diff --git a/libbutl/string-parser.hxx b/libbutl/string-parser.mxx
index b445f34..559b938 100644
--- a/libbutl/string-parser.hxx
+++ b/libbutl/string-parser.mxx
@@ -1,56 +1,67 @@
-// file : libbutl/string-parser.hxx -*- C++ -*-
+// file : libbutl/string-parser.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_STRING_PARSER_HXX
-#define LIBBUTL_STRING_PARSER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <vector>
#include <cstddef> // size_t
#include <utility> // pair
#include <stdexcept> // invalid_argument
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.string_parser;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
- class LIBBUTL_SYMEXPORT invalid_string: public std::invalid_argument
+ namespace string_parser
{
- public:
- invalid_string (std::size_t p, const std::string& d)
+ class LIBBUTL_SYMEXPORT invalid_string: public std::invalid_argument
+ {
+ public:
+ invalid_string (std::size_t p, const std::string& d)
: invalid_argument (d), position (p) {}
- std::size_t position; // Zero-based.
- };
+ std::size_t position; // Zero-based.
+ };
- class LIBBUTL_SYMEXPORT string_parser
- {
- public:
// Parse a whitespace-separated list of strings. Can contain single or
// double quoted substrings. No escaping is supported. If unquote is true,
// return one-level unquoted values. Throw invalid_string in case of
// invalid quoting.
//
- static std::vector<std::string>
+ LIBBUTL_SYMEXPORT std::vector<std::string>
parse_quoted (const std::string&, bool unquote);
// As above but return a list of string and zero-based position pairs.
// Position is useful for issuing diagnostics about an invalid string
// during second-level parsing.
//
- static std::vector<std::pair<std::string, std::size_t>>
+ LIBBUTL_SYMEXPORT std::vector<std::pair<std::string, std::size_t>>
parse_quoted_position (const std::string&, bool unquote);
// Remove a single level of quotes. Note that the format or the
// correctness of the quotation is not validated.
//
- static std::string
+ LIBBUTL_SYMEXPORT std::string
unquote (const std::string&);
- static std::vector<std::string>
+ LIBBUTL_SYMEXPORT std::vector<std::string>
unquote (const std::vector<std::string>&);
- };
+ }
}
-
-#endif // LIBBUTL_STRING_PARSER_HXX
diff --git a/libbutl/string-table.hxx b/libbutl/string-table.mxx
index 6898a52..2db8d6a 100644
--- a/libbutl/string-table.hxx
+++ b/libbutl/string-table.mxx
@@ -1,24 +1,42 @@
-// file : libbutl/string-table.hxx -*- C++ -*-
+// file : libbutl/string-table.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_STRING_TABLE_HXX
-#define LIBBUTL_STRING_TABLE_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
-#include <vector>
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <string>
+#include <vector>
#include <unordered_map>
-#include <libbutl/export.hxx>
+#include <limits> // numeric_limits
+#include <cstddef> // size_t
+#endif
-#include <libbutl/multi-index.hxx>
+// Other includes.
-namespace butl
+#ifdef __cpp_modules
+export module butl.string_table;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.multi_index;
+#else
+#include <libbutl/multi-index.mxx>
+#endif
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
- // A pool of strings and, optionally, other accompanying data in which
- // each entry is assigned an individual index (or id) of type I (e.g.,
- // uint8_t, uint16_t, etc., depending on how many entries are expected).
- // Index value 0 is reserved to indicate the "no entry" condition.
+ // A pool of strings and, optionally, other accompanying data in which each
+ // entry is assigned an individual index (or id) of type I (e.g., uint8_t,
+ // uint16_t, etc., depending on how many entries are expected). Index value
+ // 0 is reserved to indicate the "no entry" condition.
//
template <typename I, typename D>
struct string_table_element
@@ -94,5 +112,3 @@ namespace butl
}
#include <libbutl/string-table.txx>
-
-#endif // LIBBUTL_STRING_TABLE_HXX
diff --git a/libbutl/string-table.txx b/libbutl/string-table.txx
index b248ef3..f1b03bf 100644
--- a/libbutl/string-table.txx
+++ b/libbutl/string-table.txx
@@ -2,10 +2,6 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <limits> // numeric_limits
-#include <cstddef> // size_t
-#include <cassert>
-
namespace butl
{
template <typename I, typename D>
diff --git a/libbutl/tab-parser.cxx b/libbutl/tab-parser.cxx
index bf0a7dd..183e6d7 100644
--- a/libbutl/tab-parser.cxx
+++ b/libbutl/tab-parser.cxx
@@ -2,12 +2,39 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/tab-parser.hxx>
+#ifndef __cpp_modules
+#include <libbutl/tab-parser.mxx>
+#endif
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <cstdint>
+#include <stdexcept>
+
+#include <istream>
#include <sstream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.tab_parser;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
-#include <libbutl/string-parser.hxx>
+import butl.string_parser;
+#else
+#include <libbutl/string-parser.mxx>
+#endif
using namespace std;
@@ -53,7 +80,7 @@ namespace butl
{
sp = string_parser::parse_quoted_position (s, false);
}
- catch (const invalid_string& e)
+ catch (const string_parser::invalid_string& e)
{
throw parsing (name_, line_, e.position + 1, e.what ());
}
@@ -69,7 +96,7 @@ namespace butl
// tab_parsing
//
- static string
+ static inline string
format (const string& n, uint64_t l, uint64_t c, const string& d)
{
ostringstream os;
diff --git a/libbutl/tab-parser.hxx b/libbutl/tab-parser.mxx
index 688dedc..609a46d 100644
--- a/libbutl/tab-parser.hxx
+++ b/libbutl/tab-parser.mxx
@@ -1,19 +1,34 @@
-// file : libbutl/tab-parser.hxx -*- C++ -*-
+// file : libbutl/tab-parser.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_TAB_PARSER_HXX
-#define LIBBUTL_TAB_PARSER_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <iosfwd>
#include <string>
#include <vector>
-#include <istream>
#include <cstdint> // uint64_t
#include <stdexcept> // runtime_error
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.tab_parser;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
class LIBBUTL_SYMEXPORT tab_parsing: public std::runtime_error
{
@@ -68,5 +83,3 @@ namespace butl
std::uint64_t line_ = 0;
};
}
-
-#endif // LIBBUTL_TAB_PARSER_HXX
diff --git a/libbutl/target-triplet.cxx b/libbutl/target-triplet.cxx
index fc805a4..88a4262 100644
--- a/libbutl/target-triplet.cxx
+++ b/libbutl/target-triplet.cxx
@@ -2,9 +2,33 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/target-triplet.hxx>
+#ifndef __cpp_modules
+#include <libbutl/target-triplet.mxx>
+#endif
+
+// C includes.
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <ostream>
#include <stdexcept> // invalid_argument
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.target_triplet;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+#endif
using namespace std;
diff --git a/libbutl/target-triplet.hxx b/libbutl/target-triplet.mxx
index 849541d..9445aba 100644
--- a/libbutl/target-triplet.hxx
+++ b/libbutl/target-triplet.mxx
@@ -1,16 +1,31 @@
-// file : libbutl/target-triplet.hxx -*- C++ -*-
+// file : libbutl/target-triplet.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_TARGET_TRIPLET_HXX
-#define LIBBUTL_TARGET_TRIPLET_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <string>
#include <ostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.target_triplet;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+LIBBUTL_MODEXPORT namespace butl
{
// This is the ubiquitous 'target triplet' that loosely has the CPU-VENDOR-OS
// form which, these days, quite often takes the CPU-VENDOR-OS-ABI form. Plus
@@ -130,7 +145,8 @@ namespace butl
explicit
target_triplet (const std::string&);
- target_triplet () = default;
+ //target_triplet () = default;
+ target_triplet () {} //@@ MOD (VC ICE)
};
inline bool
@@ -151,5 +167,3 @@ namespace butl
return o << x.string ();
}
}
-
-#endif // LIBBUTL_TARGET_TRIPLET_HXX
diff --git a/libbutl/timestamp.cxx b/libbutl/timestamp.cxx
index b712b0c..3fececf 100644
--- a/libbutl/timestamp.cxx
+++ b/libbutl/timestamp.cxx
@@ -2,14 +2,43 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/timestamp.hxx>
+#ifndef __cpp_modules
+#include <libbutl/timestamp.mxx>
+#endif
#include <time.h> // localtime_{r,s}(), gmtime_{r,s}(), strptime(), timegm()
#include <errno.h> // EINVAL
-#include <ctime> // tm, time_t, mktime()
+#include <cassert> // Note: also gets __GLIBCXX__.
+
+// Implementation of strptime() and timegm() for Windows.
+//
+// Here we have several cases. If this is VC++, then we implement strptime()
+// via C++11 std::get_time(). And if this is MINGW GCC (or, more precisely,
+// libstdc++), then we have several problems. Firstly, GCC prior to 5 doesn't
+// implement std::get_time(). Secondly, GCC 5 and even 6 have buggy
+// std::get_time() (it cannot parse single-digit days). So what we are going
+// to do in this case is use a FreeBSD-based strptime() implementation.
+//
+// Include the C implementation here, out of module purview.
+//
+#ifdef _WIN32
+#ifdef __GLIBCXX__
+extern "C"
+{
+#include "strptime.c"
+}
+#else
+#include <locale.h> // LC_ALL
+#endif
+#endif
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <chrono>
+
+#include <ctime> // tm, time_t, mktime(), strftime()[__GLIBCXX__]
#include <cstdlib> // strtoull()
-#include <cassert>
#include <sstream>
#include <iomanip> // put_time(), setw(), dec, right
#include <cstring> // strlen(), memcpy()
@@ -17,7 +46,34 @@
#include <utility> // pair, make_pair()
#include <stdexcept> // runtime_error
-#include <libbutl/utility.hxx> // throw_generic_error()
+// Implementation of strptime() for VC.
+//
+#ifdef _WIN32
+#ifndef __GLIBCXX__
+#include <locale>
+#include <clocale>
+#include <iomanip>
+#endif
+#endif
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+module butl.timestamp;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+import butl.utility;
+#else
+#include <libbutl/utility.mxx> // throw_generic_error()
+#endif
using namespace std;
@@ -33,10 +89,6 @@ using namespace std;
// of the std::tm argument.
//
#ifdef __GLIBCXX__
-
-#include <ctime> // tm, strftime()
-#include <ostream>
-
namespace details
{
struct put_time_data
@@ -64,7 +116,6 @@ namespace details
}
using namespace details;
-
#endif
// Thread-safe implementations of gmtime() and localtime().
@@ -115,6 +166,91 @@ namespace details
}
}
+// Implementation of strptime() for VC and timegm() for Windows.
+//
+#ifdef _WIN32
+#ifndef __GLIBCXX__
+static char*
+strptime (const char* input, const char* format, tm* time)
+{
+ // VC std::get_time()-based implementation.
+ //
+ istringstream is (input);
+
+ // The original strptime() function behaves according to the process' C
+ // locale (set with std::setlocale()), which can differ from the process C++
+ // locale (set with std::locale::global()).
+ //
+ is.imbue (locale (setlocale (LC_ALL, nullptr)));
+
+ if (!(is >> get_time (time, format)))
+ return nullptr;
+ else
+ // tellg() behaves as UnformattedInputFunction, so returns failure status
+ // if eofbit is set.
+ //
+ return const_cast<char*> (
+ input + (is.eof ()
+ ? strlen (input)
+ : static_cast<size_t> (is.tellg ())));
+}
+#endif
+
+static time_t
+timegm (tm* ctm)
+{
+ const time_t e (static_cast<time_t> (-1));
+
+ // We will use an example to explain how it works. Say *ctm contains 9 AM of
+ // some day. Note that no time zone information is available.
+ //
+ // Convert it to the time from Epoch as if it's in the local time zone.
+ //
+ ctm->tm_isdst = -1;
+ time_t t (mktime (ctm));
+ if (t == e)
+ return e;
+
+ // Let's say we are in Moscow, and t contains the time passed from Epoch till
+ // 9 AM MSK. But that is not what we need. What we need is the time passed
+ // from Epoch till 9 AM GMT. This is some bigger number, as it takes longer
+ // to achieve the same calendar time for more Western location. So we need to
+ // find that offset, and increment t with it to obtain the desired value. The
+ // offset is effectively the time difference between MSK and GMT time zones.
+ //
+ tm gtm;
+ if (details::gmtime (&t, &gtm) == nullptr)
+ return e;
+
+ // gmtime() being called for the timepoint t returns 6 AM. So now we have
+ // *ctm and gtm, which value difference (3 hours) reflects the desired
+ // offset. The only problem is that we can not deduct gtm from *ctm, to get
+ // the offset expressed as time_t. To do that we need to apply to both of
+ // them the same conversion function transforming std::tm to std::time_t. The
+ // mktime() can do that, so the expression (mktime(ctm) - mktime(&gtm))
+ // calculates the desired offset.
+ //
+ // To ensure mktime() works exactly the same way for both cases, we need to
+ // reset Daylight Saving Time flag for each of *ctm and gtm.
+ //
+ ctm->tm_isdst = 0;
+ time_t lt (mktime (ctm));
+ if (lt == e)
+ return e;
+
+ gtm.tm_isdst = 0;
+ time_t gt (mktime (&gtm));
+ if (gt == e)
+ return e;
+
+ // C11 standard specifies time_t to be a real type (integer and real floating
+ // types are collectively called real types). So we can not consider it to be
+ // signed.
+ //
+ return lt > gt ? t + (lt - gt) : t - (gt - lt);
+}
+#endif // _WIN32
+
namespace butl
{
ostream&
@@ -337,123 +473,7 @@ namespace butl
to_stream (o, d, nsec);
return o.str ();
}
-}
-
-// Implementation of strptime() and timegm() for Windows.
-//
-// Here we have several cases. If this is VC++, then we implement strptime()
-// via C++11 std::get_time(). And if this is MINGW GCC (or, more precisely,
-// libstdc++), then we have several problems. Firstly, GCC prior to 5 doesn't
-// implement std::get_time(). Secondly, GCC 5 and even 6 have buggy
-// std::get_time() (it cannot parse single-digit days). So what we are going
-// to do in this case is use a FreeBSD-based strptime() implementation.
-//
-#ifdef _WIN32
-
-#ifdef __GLIBCXX__
-
-// Fallback to a FreeBSD-based implementation.
-//
-extern "C"
-{
-#include "strptime.c"
-}
-
-#else // NOT __GLIBCXX__
-
-#include <ctime> // tm
-#include <locale>
-#include <clocale>
-#include <iomanip>
-#include <cstring> // strlen()
-
-// VC++ std::get_time()-based implementation.
-//
-static char*
-strptime (const char* input, const char* format, tm* time)
-{
- istringstream is (input);
-
- // The original strptime() function behaves according to the process' C
- // locale (set with std::setlocale()), which can differ from the process C++
- // locale (set with std::locale::global()).
- //
- is.imbue (locale (setlocale (LC_ALL, nullptr)));
-
- if (!(is >> get_time (time, format)))
- return nullptr;
- else
- // tellg() behaves as UnformattedInputFunction, so returns failure status
- // if eofbit is set.
- //
- return const_cast<char*> (
- input + (is.eof ()
- ? strlen (input)
- : static_cast<size_t> (is.tellg ())));
-}
-
-#endif // __GLIBCXX__
-
-#include <ctime> // time_t, tm, mktime()
-static time_t
-timegm (tm* ctm)
-{
- const time_t e (static_cast<time_t> (-1));
-
- // We will use an example to explain how it works. Say *ctm contains 9 AM of
- // some day. Note that no time zone information is available.
- //
- // Convert it to the time from Epoch as if it's in the local time zone.
- //
- ctm->tm_isdst = -1;
- time_t t (mktime (ctm));
- if (t == e)
- return e;
-
- // Let's say we are in Moscow, and t contains the time passed from Epoch till
- // 9 AM MSK. But that is not what we need. What we need is the time passed
- // from Epoch till 9 AM GMT. This is some bigger number, as it takes longer
- // to achieve the same calendar time for more Western location. So we need to
- // find that offset, and increment t with it to obtain the desired value. The
- // offset is effectively the time difference between MSK and GMT time zones.
- //
- tm gtm;
- if (details::gmtime (&t, &gtm) == nullptr)
- return e;
-
- // gmtime() being called for the timepoint t returns 6 AM. So now we have
- // *ctm and gtm, which value difference (3 hours) reflects the desired
- // offset. The only problem is that we can not deduct gtm from *ctm, to get
- // the offset expressed as time_t. To do that we need to apply to both of
- // them the same conversion function transforming std::tm to std::time_t. The
- // mktime() can do that, so the expression (mktime(ctm) - mktime(&gtm))
- // calculates the desired offset.
- //
- // To ensure mktime() works exactly the same way for both cases, we need to
- // reset Daylight Saving Time flag for each of *ctm and gtm.
- //
- ctm->tm_isdst = 0;
- time_t lt (mktime (ctm));
- if (lt == e)
- return e;
-
- gtm.tm_isdst = 0;
- time_t gt (mktime (&gtm));
- if (gt == e)
- return e;
-
- // C11 standard specifies time_t to be a real type (integer and real floating
- // types are collectively called real types). So we can not consider it to be
- // signed.
- //
- return lt > gt ? t + (lt - gt) : t - (gt - lt);
-}
-
-#endif // _WIN32
-
-namespace butl
-{
static pair<tm, chrono::nanoseconds>
from_string (const char* input, const char* format, const char** end)
{
diff --git a/libbutl/timestamp.hxx b/libbutl/timestamp.mxx
index c1621a7..cde0e01 100644
--- a/libbutl/timestamp.hxx
+++ b/libbutl/timestamp.mxx
@@ -1,18 +1,35 @@
-// file : libbutl/timestamp.hxx -*- C++ -*-
+// file : libbutl/timestamp.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_TIMESTAMP_HXX
-#define LIBBUTL_TIMESTAMP_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
-#include <chrono>
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <iosfwd>
+#include <string>
+#include <chrono>
+#endif
-#include <libbutl/export.hxx>
+// Other includes.
-#include <libbutl/path.hxx>
+#ifdef __cpp_modules
+export module butl.timestamp;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
-namespace butl
+//@@ MOD TODO: should't we re-export chrono (for somparison operator, etc)?
+// or ADL should kick in?
+
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// On all three main platforms that we target (GNU/Linux, Windows (both
// VC++ and GCC/MinGW64), and MacOS X) with recent C++ runtimes,
@@ -42,10 +59,17 @@ namespace butl
// Generally-useful special values. Note that unknown is less than
// nonexistent and is less than any non-special value.
//
+#if defined(__cpp_modules) && defined(__clang__) //@@ MOD Clang duplicate sym.
+ inline const timestamp::rep timestamp_unknown_rep = -1;
+ inline const timestamp timestamp_unknown = timestamp (duration (-1));
+ inline const timestamp::rep timestamp_nonexistent_rep = 0;
+ inline const timestamp timestamp_nonexistent = timestamp (duration (0));
+#else
const timestamp::rep timestamp_unknown_rep = -1;
const timestamp timestamp_unknown = timestamp (duration (-1));
const timestamp::rep timestamp_nonexistent_rep = 0;
const timestamp timestamp_nonexistent = timestamp (duration (0));
+#endif
// Print human-readable representation of the timestamp.
//
@@ -165,5 +189,3 @@ namespace butl
bool local,
const char** end = nullptr);
}
-
-#endif // LIBBUTL_TIMESTAMP_HXX
diff --git a/libbutl/utility.cxx b/libbutl/utility.cxx
index 8ce2cbc..c8e4e85 100644
--- a/libbutl/utility.cxx
+++ b/libbutl/utility.cxx
@@ -2,15 +2,39 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <libbutl/utility.hxx>
+#ifndef __cpp_modules
+#include <libbutl/utility.mxx>
+#endif
#ifdef _WIN32
-# include <libbutl/win32-utility.hxx>
+#include <libbutl/win32-utility.hxx>
#endif
+#ifndef __cpp_lib_modules
#include <string>
+#include <cstddef>
+#include <utility>
+
#include <ostream>
#include <system_error>
+#endif
+
+#include <libbutl/ft/lang.hxx>
+#include <libbutl/ft/exception.hxx>
+
+#ifdef __cpp_modules
+module butl.utility;
+
+// Only imports additional to interface.
+#ifdef __clang__
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
+
+#endif
+
namespace butl
{
diff --git a/libbutl/utility.ixx b/libbutl/utility.ixx
index e45a729..cec61c8 100644
--- a/libbutl/utility.ixx
+++ b/libbutl/utility.ixx
@@ -2,14 +2,6 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef _WIN32
-# include <strings.h> // strcasecmp(), strncasecmp()
-#else
-# include <string.h> // _stricmp(), _strnicmp()
-#endif
-
-#include <cctype> // toupper(), tolower(), isalpha(), isdigit(), isalnum()
-
namespace butl
{
inline char
diff --git a/libbutl/utility.hxx b/libbutl/utility.mxx
index 3a994bb..6a50186 100644
--- a/libbutl/utility.hxx
+++ b/libbutl/utility.mxx
@@ -1,24 +1,46 @@
-// file : libbutl/utility.hxx -*- C++ -*-
+// file : libbutl/utility.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_UTILITY_HXX
-#define LIBBUTL_UTILITY_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+
+#ifndef _WIN32
+#if !defined(__cpp_lib_modules) || !defined(__clang__) //@@ MOD Clang ICE
+# include <strings.h> // strcasecmp(), strncasecmp()
+#endif
+#else
+# include <string.h> // _stricmp(), _strnicmp()
+#endif
+#ifndef __cpp_lib_modules
#include <string>
-#include <iosfwd> // ostream
-#include <cstddef> // size_t
-#include <utility> // move(), forward()
-#include <cstring> // strcmp(), strlen()
-#include <libbutl/ft/exception.hxx> // uncaught_exceptions
-#include <exception> // exception, uncaught_exception(s)()
+#include <iosfwd> // ostream
+#include <cstddef> // size_t
+#include <utility> // move(), forward()
+#include <cstring> // strcmp(), strlen()
+#include <exception> // exception, uncaught_exception(s)()
+//#include <functional> // hash
+
+#include <cctype> // toupper(), tolower(), isalpha(), isdigit(), isalnum()
+#endif
+
#include <libbutl/ft/lang.hxx> // thread_local
+#include <libbutl/ft/exception.hxx> // uncaught_exceptions
-//#include <functional> // hash
+#ifdef __cpp_modules
+export module butl.utility;
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+#endif
#include <libbutl/export.hxx>
-namespace butl
+
+LIBBUTL_MODEXPORT namespace butl
{
// Throw std::system_error with generic_category or system_category,
// respectively.
@@ -53,13 +75,14 @@ namespace butl
// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap07.html#tag_07_02)
//
char ucase (char);
- std::string ucase (const char*, std::size_t = std::string::npos);
+ std::string ucase (const char*, std::size_t = -1 /*@@ MOD VC ICE = std::string::npos*/);
+
std::string ucase (const std::string&);
std::string& ucase (std::string&);
void ucase (char*, std::size_t);
char lcase (char);
- std::string lcase (const char*, std::size_t = std::string::npos);
+ std::string lcase (const char*, std::size_t = -1 /*@@ MOD VC ICE = std::string::npos*/);
std::string lcase (const std::string&);
std::string& lcase (std::string&);
void lcase (char*, std::size_t);
@@ -77,12 +100,12 @@ namespace butl
int casecmp (char, char);
int casecmp (const std::string&, const std::string&,
- std::size_t = std::string::npos);
+ std::size_t = -1 /*@@ MOD VC ICE std::string::npos*/);
int casecmp (const std::string&, const char*,
- std::size_t = std::string::npos);
+ std::size_t = -1 /*@@ MOD VC ICE std::string::npos*/);
- int casecmp (const char*, const char*, std::size_t = std::string::npos);
+ int casecmp (const char*, const char*, std::size_t = -1 /*MOD VC ICE std::string::npos*/);
// Case-insensitive key comparators (i.e., to be used in sets, maps, etc).
//
@@ -246,7 +269,7 @@ namespace butl
#endif
}
-namespace std
+LIBBUTL_MODEXPORT namespace std
{
// Sanitize the exception description before printing. This includes:
//
@@ -260,5 +283,3 @@ namespace std
}
#include <libbutl/utility.ixx>
-
-#endif // LIBBUTL_UTILITY_HXX
diff --git a/libbutl/vector-view.hxx b/libbutl/vector-view.mxx
index 98b314c..e2c9d7e 100644
--- a/libbutl/vector-view.hxx
+++ b/libbutl/vector-view.mxx
@@ -1,17 +1,33 @@
-// file : libbutl/vector-view.hxx -*- C++ -*-
+// file : libbutl/vector-view.mxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_VECTOR_VIEW_HXX
-#define LIBBUTL_VECTOR_VIEW_HXX
+#ifndef __cpp_modules
+#pragma once
+#endif
+// C includes.
+
+#ifndef __cpp_lib_modules
#include <vector>
#include <cstddef> // size_t, ptrdiff_t
#include <utility> // swap()
#include <iterator> // reverse_iterator
#include <stdexcept> // out_of_range
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+export module butl.vector_view;
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+#endif
-namespace butl
+#include <libbutl/export.hxx>
+
+LIBBUTL_MODEXPORT namespace butl
{
// In our version a const view allows the modification of the elements
// unless T is made const (the same semantics as in smart pointers).
@@ -116,5 +132,3 @@ namespace butl
template<typename T> bool operator<= (vector_view<T> l, vector_view<T> r);
template<typename T> bool operator>= (vector_view<T> l, vector_view<T> r);
}
-
-#endif // LIBBUTL_VECTOR_VIEW_HXX
diff --git a/libbutl/version.hxx.in b/libbutl/version.hxx.in
index 780d21a..add5154 100644
--- a/libbutl/version.hxx.in
+++ b/libbutl/version.hxx.in
@@ -2,7 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_VERSION // Note: using the version macro itself.
+#pragma once
// Note: using build2 standard versioning scheme. The numeric version format
// is AAABBBCCCDDDE where:
@@ -36,5 +36,3 @@
#define LIBBUTL_SNAPSHOT $libbutl.version.snapshot_sn$ULL
#define LIBBUTL_SNAPSHOT_ID "$libbutl.version.snapshot_id$"
-
-#endif // LIBBUTL_VERSION
diff --git a/libbutl/win32-utility.cxx b/libbutl/win32-utility.cxx
index c16f8cc..9e7b936 100644
--- a/libbutl/win32-utility.cxx
+++ b/libbutl/win32-utility.cxx
@@ -9,7 +9,11 @@
//
#ifdef _WIN32
+#ifndef __cpp_lib_modules
#include <memory> // unique_ptr
+#else
+import std.core;
+#endif
using namespace std;
diff --git a/libbutl/win32-utility.hxx b/libbutl/win32-utility.hxx
index d9a3bcb..8c1e6d7 100644
--- a/libbutl/win32-utility.hxx
+++ b/libbutl/win32-utility.hxx
@@ -2,8 +2,7 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#ifndef LIBBUTL_WIN32_UTILITY_HXX
-#define LIBBUTL_WIN32_UTILITY_HXX
+#pragma once
// Use this header to include <windows.h> and a couple of Win32-specific
// utilities.
@@ -33,7 +32,11 @@
# endif
#endif
+#ifndef __cpp_lib_modules
#include <string>
+#else
+import std.core;
+#endif
#include <libbutl/export.hxx>
@@ -50,5 +53,3 @@ namespace butl
};
#endif // _WIN32
-
-#endif // LIBBUTL_WIN32_UTILITY_HXX
diff --git a/tests/base64/buildfile b/tests/base64/buildfile
index 710499e..535b9dc 100644
--- a/tests/base64/buildfile
+++ b/tests/base64/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/base64/driver.cxx b/tests/base64/driver.cxx
index 040eaf8..fb65a49 100644
--- a/tests/base64/driver.cxx
+++ b/tests/base64/driver.cxx
@@ -2,11 +2,25 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <string>
+#include <vector>
#include <sstream>
-#include <cassert>
+#endif
-#include <libbutl/base64.hxx>
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.base64;
+#else
+#include <libbutl/base64.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/build/root.build b/tests/build/root.build
index 633ccb3..6c98ba9 100644
--- a/tests/build/root.build
+++ b/tests/build/root.build
@@ -2,6 +2,11 @@
# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
+using cxx.guess
+
+if ($force_modules != true && $cxx.id == 'clang')
+ cxx.features.modules = false
+
cxx.std = experimental
using cxx
diff --git a/tests/cpfile/buildfile b/tests/cpfile/buildfile
index 0d95110..41275fa 100644
--- a/tests/cpfile/buildfile
+++ b/tests/cpfile/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/cpfile/driver.cxx b/tests/cpfile/driver.cxx
index 3a19322..db529ba 100644
--- a/tests/cpfile/driver.cxx
+++ b/tests/cpfile/driver.cxx
@@ -2,14 +2,29 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <ios>
#include <string>
-#include <cassert>
#include <system_error>
+#endif
-#include <libbutl/path.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/filesystem.hxx>
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.fdstream;
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/curl/buildfile b/tests/curl/buildfile
index 20617cf..dae375b 100644
--- a/tests/curl/buildfile
+++ b/tests/curl/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/curl/driver.cxx b/tests/curl/driver.cxx
index b5fc400..326d717 100644
--- a/tests/curl/driver.cxx
+++ b/tests/curl/driver.cxx
@@ -2,12 +2,35 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <iostream>
#include <system_error>
-
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/curl.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.curl;
+import butl.path;
+import butl.process;
+import butl.utility; // operator<<(ostream, exception)
+import butl.fdstream;
+
+import butl.optional; // @@ MOD Clang should not be necessary.
+import butl.small_vector; // @@ MOD Clang should not be necessary.
+#else
+#include <libbutl/curl.mxx>
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/dir-iterator/buildfile b/tests/dir-iterator/buildfile
index e536536..7f83e4f 100644
--- a/tests/dir-iterator/buildfile
+++ b/tests/dir-iterator/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/dir-iterator/driver.cxx b/tests/dir-iterator/driver.cxx
index f584c68..1adef6f 100644
--- a/tests/dir-iterator/driver.cxx
+++ b/tests/dir-iterator/driver.cxx
@@ -2,14 +2,30 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <cstddef> // size_t
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <cstddef> // size_t
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/path-io.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/filesystem.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.path_io;
+import butl.utility;
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/path-io.mxx>
+#include <libbutl/utility.mxx> // operator<<(ostream, exception)
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/fdstream/buildfile b/tests/fdstream/buildfile
index 5440bc1..6028f3f 100644
--- a/tests/fdstream/buildfile
+++ b/tests/fdstream/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx
index 42414bc..dd70cff 100644
--- a/tests/fdstream/driver.cxx
+++ b/tests/fdstream/driver.cxx
@@ -2,6 +2,9 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#ifndef _WIN32
# include <chrono>
# include <thread> // this_thread::sleep_for()
@@ -11,18 +14,35 @@
#include <string>
#include <vector>
#include <iomanip>
-#include <cassert>
#include <sstream>
#include <fstream>
#include <utility> // move()
#include <iostream>
#include <exception>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/timestamp.hxx>
-#include <libbutl/filesystem.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#ifndef _WIN32
+//@@ MOD TODO import std.threading;
+#endif
+#endif
+import butl.path;
+import butl.process;
+import butl.fdstream;
+import butl.timestamp;
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/timestamp.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/link/buildfile b/tests/link/buildfile
index 9d4f6b5..17e3eac 100644
--- a/tests/link/buildfile
+++ b/tests/link/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/link/driver.cxx b/tests/link/driver.cxx
index a5e94bb..352cadd 100644
--- a/tests/link/driver.cxx
+++ b/tests/link/driver.cxx
@@ -2,14 +2,28 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <set>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <set>
#include <utility> // pair
#include <system_error>
+#endif
-#include <libbutl/path.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/filesystem.hxx>
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.path;
+import butl.fdstream;
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/manifest-parser/buildfile b/tests/manifest-parser/buildfile
index b57cac6..2a89e29 100644
--- a/tests/manifest-parser/buildfile
+++ b/tests/manifest-parser/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/manifest-parser/driver.cxx b/tests/manifest-parser/driver.cxx
index 037df96..76959e5 100644
--- a/tests/manifest-parser/driver.cxx
+++ b/tests/manifest-parser/driver.cxx
@@ -2,14 +2,27 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <vector>
#include <string>
#include <utility> // pair
-#include <cassert>
#include <sstream>
#include <iostream>
-
-#include <libbutl/manifest-parser.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.manifest_parser;
+#else
+#include <libbutl/manifest-parser.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/manifest-roundtrip/buildfile b/tests/manifest-roundtrip/buildfile
index a2fb3ac..5cd296f 100644
--- a/tests/manifest-roundtrip/buildfile
+++ b/tests/manifest-roundtrip/buildfile
@@ -4,5 +4,11 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
exe{driver}: test.roundtrip = manifest
diff --git a/tests/manifest-roundtrip/driver.cxx b/tests/manifest-roundtrip/driver.cxx
index 2068409..1f0b311 100644
--- a/tests/manifest-roundtrip/driver.cxx
+++ b/tests/manifest-roundtrip/driver.cxx
@@ -3,12 +3,29 @@
// license : MIT; see accompanying LICENSE file
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/fdstream.hxx>
-#include <libbutl/manifest-parser.hxx>
-#include <libbutl/manifest-serializer.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.utility; // operator<<(ostream, exception)
+import butl.fdstream;
+import butl.manifest_parser;
+import butl.manifest_serializer;
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/manifest-parser.mxx>
+#include <libbutl/manifest-serializer.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/manifest-serializer/buildfile b/tests/manifest-serializer/buildfile
index d13daab..df633ae 100644
--- a/tests/manifest-serializer/buildfile
+++ b/tests/manifest-serializer/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/manifest-serializer/driver.cxx b/tests/manifest-serializer/driver.cxx
index dad96bd..f373ecf 100644
--- a/tests/manifest-serializer/driver.cxx
+++ b/tests/manifest-serializer/driver.cxx
@@ -2,14 +2,27 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <vector>
#include <string>
#include <utility> // pair
-#include <cassert>
#include <sstream>
#include <iostream>
-
-#include <libbutl/manifest-serializer.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.manifest_serializer;
+#else
+#include <libbutl/manifest-serializer.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/mventry/buildfile b/tests/mventry/buildfile
index b665b61..d9af3a2 100644
--- a/tests/mventry/buildfile
+++ b/tests/mventry/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/mventry/driver.cxx b/tests/mventry/driver.cxx
index 5639c2b..eab2ce3 100644
--- a/tests/mventry/driver.cxx
+++ b/tests/mventry/driver.cxx
@@ -2,12 +2,28 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <iostream>
#include <system_error>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/filesystem.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.utility; // operator<<(ostream, exception)
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/openssl/buildfile b/tests/openssl/buildfile
index 7713f14..08b0878 100644
--- a/tests/openssl/buildfile
+++ b/tests/openssl/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/openssl/driver.cxx b/tests/openssl/driver.cxx
index b0e37ae..092b2ba 100644
--- a/tests/openssl/driver.cxx
+++ b/tests/openssl/driver.cxx
@@ -2,14 +2,36 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <vector>
#include <iostream>
#include <iterator>
#include <system_error>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.utility; // operator<<(ostream, exception)
+import butl.openssl;
+import butl.process;
+import butl.fdstream; // nullfd
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/openssl.hxx>
+import butl.optional; // @@ MOD Clang should not be necessary.
+import butl.small_vector; // @@ MOD Clang should not be necessary.
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/openssl.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/pager/buildfile b/tests/pager/buildfile
index 1c1e9f4..d7d0123 100644
--- a/tests/pager/buildfile
+++ b/tests/pager/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/pager/driver.cxx b/tests/pager/driver.cxx
index 87c811d..6842cef 100644
--- a/tests/pager/driver.cxx
+++ b/tests/pager/driver.cxx
@@ -2,15 +2,28 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <ios> // ios_base::failure
#include <vector>
#include <string>
#include <utility> // move()
-#include <cassert>
#include <sstream>
#include <iostream>
-
-#include <libbutl/pager.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.pager;
+#else
+#include <libbutl/pager.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/path-entry/buildfile b/tests/path-entry/buildfile
index 58e315c..e6515ae 100644
--- a/tests/path-entry/buildfile
+++ b/tests/path-entry/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/path-entry/driver.cxx b/tests/path-entry/driver.cxx
index 4f36f61..c69bf9c 100644
--- a/tests/path-entry/driver.cxx
+++ b/tests/path-entry/driver.cxx
@@ -2,11 +2,26 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <iostream>
#include <system_error>
-
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/filesystem.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.utility; // operator<<(ostream, exception)
+import butl.filesystem;
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/path/buildfile b/tests/path/buildfile
index e7f19f2..aa39b2d 100644
--- a/tests/path/buildfile
+++ b/tests/path/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/path/driver.cxx b/tests/path/driver.cxx
index 4d859b3..c2919c0 100644
--- a/tests/path/driver.cxx
+++ b/tests/path/driver.cxx
@@ -3,11 +3,25 @@
// license : MIT; see accompanying LICENSE file
#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <iostream>
#include <type_traits>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/path-io.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.path_io;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/path-io.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/prefix-map/buildfile b/tests/prefix-map/buildfile
index 5c2dd69..140fda9 100644
--- a/tests/prefix-map/buildfile
+++ b/tests/prefix-map/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/prefix-map/driver.cxx b/tests/prefix-map/driver.cxx
index abf7e01..3e165b2 100644
--- a/tests/prefix-map/driver.cxx
+++ b/tests/prefix-map/driver.cxx
@@ -2,11 +2,24 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <string>
#include <cassert>
-#include <iostream>
-#include <libbutl/prefix-map.hxx>
+#ifndef __cpp_lib_modules
+#include <string>
+#include <iostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.prefix_map;
+#else
+#include <libbutl/prefix-map.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/process-run/buildfile b/tests/process-run/buildfile
index 770357c..5200af7 100644
--- a/tests/process-run/buildfile
+++ b/tests/process-run/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/process-run/driver.cxx b/tests/process-run/driver.cxx
index 695fdb9..765bd7d 100644
--- a/tests/process-run/driver.cxx
+++ b/tests/process-run/driver.cxx
@@ -2,12 +2,31 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
-#include <libbutl/small-vector.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.process;
+import butl.optional; // @@ MOD Clang shouldn't be needed.
+import butl.fdstream;
+import butl.small_vector;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx>
+#include <libbutl/small-vector.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/process/buildfile b/tests/process/buildfile
index ddb4688..2ecc915 100644
--- a/tests/process/buildfile
+++ b/tests/process/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/process/driver.cxx b/tests/process/driver.cxx
index 0338af2..01f2c30 100644
--- a/tests/process/driver.cxx
+++ b/tests/process/driver.cxx
@@ -4,17 +4,34 @@
#include <stdlib.h> // getenv(), setenv(), _putenv()
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <ios>
#include <string>
#include <vector>
-#include <cassert>
-#include <iostream>
#include <iterator> // istreambuf_iterator, ostream_iterator
#include <algorithm> // copy()
+#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.process;
+import butl.optional;
+import butl.fdstream;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/optional.mxx>
+#include <libbutl/fdstream.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/progress/buildfile b/tests/progress/buildfile
index 19e85c0..d8cb6d6 100644
--- a/tests/progress/buildfile
+++ b/tests/progress/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/progress/driver.cxx b/tests/progress/driver.cxx
index 0ff68f0..c8c2080 100644
--- a/tests/progress/driver.cxx
+++ b/tests/progress/driver.cxx
@@ -4,20 +4,43 @@
#ifndef _WIN32
# include <unistd.h> // write()
-
-# include <thread> // this_thread::sleep_for()
#else
# include <libbutl/win32-utility.hxx>
-
# include <io.h> //_write()
#endif
+#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <cstddef> // size_t
#include <iostream>
+#ifndef _WIN32
+# include <thread> // this_thread::sleep_for()
+#endif
+#endif
-#include <libbutl/process.hxx>
-#include <libbutl/fdstream.hxx> // fdnull(), stderr_fd()
-#include <libbutl/diagnostics.hxx>
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#ifndef _WIN32
+//@@ MOD TODO import std.threading;
+#endif
+#endif
+import butl.process;
+import butl.fdstream;
+import butl.diagnostics;
+
+import butl.optional; // @@ MOD Clang should not be necessary.
+import butl.small_vector; // @@ MOD Clang should not be necessary.
+#else
+#include <libbutl/process.mxx>
+#include <libbutl/fdstream.mxx> // fdnull(), stderr_fd()
+#include <libbutl/diagnostics.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/regex/buildfile b/tests/regex/buildfile
index baf4bca..ae7e2c3 100644
--- a/tests/regex/buildfile
+++ b/tests/regex/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/regex/driver.cxx b/tests/regex/driver.cxx
index 054eb31..d48b716 100644
--- a/tests/regex/driver.cxx
+++ b/tests/regex/driver.cxx
@@ -2,13 +2,27 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <string>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
#include <exception>
+#endif
+
+// Other includes.
-#include <libbutl/regex.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.regex;
+import butl.utility; // operator<<(ostream, exception)
+#else
+#include <libbutl/regex.mxx>
+#include <libbutl/utility.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/sendmail/buildfile b/tests/sendmail/buildfile
index a83cf40..a854e89 100644
--- a/tests/sendmail/buildfile
+++ b/tests/sendmail/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/sendmail/driver.cxx b/tests/sendmail/driver.cxx
index e48c6b4..f5c9227 100644
--- a/tests/sendmail/driver.cxx
+++ b/tests/sendmail/driver.cxx
@@ -2,12 +2,34 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <iostream>
#include <system_error>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.process;
+import butl.utility; // operator<<(ostream, exception)
+import butl.sendmail;
+import butl.fdstream;
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/sendmail.hxx>
+import butl.optional; // @@ MOD Clang should not be necessary.
+import butl.small_vector; // @@ MOD Clang should not be necessary.
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/process.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/sendmail.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/sha256/buildfile b/tests/sha256/buildfile
index 627b78f..fb490d0 100644
--- a/tests/sha256/buildfile
+++ b/tests/sha256/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/sha256/driver.cxx b/tests/sha256/driver.cxx
index 2d2f963..191756c 100644
--- a/tests/sha256/driver.cxx
+++ b/tests/sha256/driver.cxx
@@ -1,12 +1,25 @@
-// file : tests/triplet/driver.cxx -*- C++ -*-
+// file : tests/sha256/driver.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <string>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/sha256.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.sha256;
+#else
+#include <libbutl/sha256.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/small-vector/buildfile b/tests/small-vector/buildfile
index 33be9ad..16d61f8 100644
--- a/tests/small-vector/buildfile
+++ b/tests/small-vector/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/small-vector/driver.cxx b/tests/small-vector/driver.cxx
index c7cafd4..fe386a4 100644
--- a/tests/small-vector/driver.cxx
+++ b/tests/small-vector/driver.cxx
@@ -2,11 +2,25 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <string>
#include <cassert>
-#include <iostream>
-#include <libbutl/small-vector.hxx>
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
+#include <iostream>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.small_vector;
+#else
+#include <libbutl/small-vector.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/standard-version/buildfile b/tests/standard-version/buildfile
index 0583b62..eb30733 100644
--- a/tests/standard-version/buildfile
+++ b/tests/standard-version/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/standard-version/driver.cxx b/tests/standard-version/driver.cxx
index fa149ae..c6f9c11 100644
--- a/tests/standard-version/driver.cxx
+++ b/tests/standard-version/driver.cxx
@@ -2,14 +2,28 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <ios> // ios::failbit, ios::badbit
#include <string>
-#include <cassert>
#include <iostream>
#include <stdexcept> // invalid_argument
-
-#include <libbutl/utility.hxx> // operator<<(ostream,exception)
-#include <libbutl/standard-version.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.utility; // operator<<(ostream,exception)
+import butl.standard_version;
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/standard-version.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/strcase/buildfile b/tests/strcase/buildfile
index 71fec53..efe8442 100644
--- a/tests/strcase/buildfile
+++ b/tests/strcase/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/strcase/driver.cxx b/tests/strcase/driver.cxx
index f7f4bd1..285892d 100644
--- a/tests/strcase/driver.cxx
+++ b/tests/strcase/driver.cxx
@@ -2,10 +2,22 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <string>
#include <cassert>
-#include <libbutl/utility.hxx>
+#ifndef __cpp_lib_modules
+#include <string>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+#endif
+import butl.utility;
+#else
+#include <libbutl/utility.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/string-parser/buildfile b/tests/string-parser/buildfile
index 5969cd0..4613df1 100644
--- a/tests/string-parser/buildfile
+++ b/tests/string-parser/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/string-parser/driver.cxx b/tests/string-parser/driver.cxx
index 09443f2..f454a6f 100644
--- a/tests/string-parser/driver.cxx
+++ b/tests/string-parser/driver.cxx
@@ -2,17 +2,30 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <ios> // ios::failbit, ios::badbit
-#include <vector>
-#include <string>
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
+#include <vector>
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/utility.hxx> // operator<<(ostream,exception)
-#include <libbutl/string-parser.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.utility; // operator<<(ostream,exception)
+import butl.string_parser;
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/string-parser.mxx>
+#endif
using namespace std;
-using namespace butl;
+using namespace butl::string_parser;
// Usage: argv[0] [-l] [-u] [-p]
//
@@ -54,8 +67,7 @@ try
string l;
while (getline (cin, l))
{
- vector<pair<string, size_t>> v (
- string_parser::parse_quoted_position (l, unquote));
+ vector<pair<string, size_t>> v (parse_quoted_position (l, unquote));
if (!spl)
{
diff --git a/tests/tab-parser/buildfile b/tests/tab-parser/buildfile
index 0583b62..eb30733 100644
--- a/tests/tab-parser/buildfile
+++ b/tests/tab-parser/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/tab-parser/driver.cxx b/tests/tab-parser/driver.cxx
index 238c12a..d5ff5a0 100644
--- a/tests/tab-parser/driver.cxx
+++ b/tests/tab-parser/driver.cxx
@@ -2,12 +2,26 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <ios> // ios::failbit, ios::badbit
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/utility.hxx> // operator<<(ostream,exception)
-#include <libbutl/tab-parser.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.utility; // operator<<(ostream,exception)
+import butl.tab_parser;
+#else
+#include <libbutl/utility.mxx>
+#include <libbutl/tab-parser.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/target-triplet/buildfile b/tests/target-triplet/buildfile
index b8ca712..7dec846 100644
--- a/tests/target-triplet/buildfile
+++ b/tests/target-triplet/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/target-triplet/driver.cxx b/tests/target-triplet/driver.cxx
index b446a6f..5e61a46 100644
--- a/tests/target-triplet/driver.cxx
+++ b/tests/target-triplet/driver.cxx
@@ -3,10 +3,24 @@
// license : MIT; see accompanying LICENSE file
#include <cassert>
+
+#ifndef __cpp_lib_modules
+#include <string>
#include <iostream>
#include <stdexcept> // invalid_argument
-
-#include <libbutl/target-triplet.hxx>
+#endif
+
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.target_triplet;
+#else
+#include <libbutl/target-triplet.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/timestamp/buildfile b/tests/timestamp/buildfile
index 085daf0..c554fc3 100644
--- a/tests/timestamp/buildfile
+++ b/tests/timestamp/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs
diff --git a/tests/timestamp/driver.cxx b/tests/timestamp/driver.cxx
index 661deb2..ec4c49d 100644
--- a/tests/timestamp/driver.cxx
+++ b/tests/timestamp/driver.cxx
@@ -4,15 +4,28 @@
#include <time.h> // tzset() (POSIX), _tzset() (Windows)
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <chrono>
#include <locale>
#include <clocale>
-#include <cassert>
#include <sstream>
#include <iomanip>
#include <system_error>
+#endif
-#include <libbutl/timestamp.hxx>
+// Other includes.
+
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.timestamp;
+#else
+#include <libbutl/timestamp.mxx>
+#endif
using namespace std;
using namespace butl;
diff --git a/tests/wildcard/buildfile b/tests/wildcard/buildfile
index fc8e94b..90e8b58 100644
--- a/tests/wildcard/buildfile
+++ b/tests/wildcard/buildfile
@@ -4,4 +4,10 @@
import libs = libbutl%lib{butl}
+if ($cxx.features.modules && ($force_std_modules == true || $cxx.id != 'msvc'))
+{
+ import libs += libstd-modules%liba{std-modules}
+ cxx.poptions += -D__cpp_lib_modules
+}
+
exe{driver}: {hxx cxx}{*} $libs test{testscript}
diff --git a/tests/wildcard/driver.cxx b/tests/wildcard/driver.cxx
index 502726f..d95d7cd 100644
--- a/tests/wildcard/driver.cxx
+++ b/tests/wildcard/driver.cxx
@@ -2,18 +2,34 @@
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
+#include <cassert>
+
+#ifndef __cpp_lib_modules
#include <map>
#include <string>
#include <vector>
-#include <cassert>
-#include <iostream>
#include <algorithm> // sort()
#include <exception>
+#include <iostream>
+#endif
+
+// Other includes.
-#include <libbutl/path.hxx>
-#include <libbutl/utility.hxx> // operator<<(ostream, exception)
-#include <libbutl/optional.hxx>
-#include <libbutl/filesystem.hxx>
+#ifdef __cpp_modules
+#ifdef __cpp_lib_modules
+import std.core;
+import std.io;
+#endif
+import butl.path;
+import butl.utility; // operator<<(ostream, exception)
+import butl.optional;
+import butl.filesystem;
+#else
+#include <libbutl/path.mxx>
+#include <libbutl/utility.mxx>
+#include <libbutl/optional.mxx>
+#include <libbutl/filesystem.mxx>
+#endif
using namespace std;
using namespace butl;