mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 01:59:02 +00:00
Make trivstring class ready for use
The interface is now 100% unit tested, and the typedefs depend on the new STD_STRING_USES_COW configuration variable. The only missing bit is to detect clang and disable STD_STRING_USES_COW for clang.
This commit is contained in:
parent
46f7b578b2
commit
83bee109db
@ -259,10 +259,13 @@ if(UNIX OR MINGW)
|
|||||||
endif()
|
endif()
|
||||||
set(LYX_GCC11_MODE "${CXX11_FLAG}")
|
set(LYX_GCC11_MODE "${CXX11_FLAG}")
|
||||||
endif()
|
endif()
|
||||||
|
set(STD_STRING_USES_COW 1)
|
||||||
else()
|
else()
|
||||||
if(MSVC10)
|
if(MSVC10)
|
||||||
set(LYX_USE_TR1 1)
|
set(LYX_USE_TR1 1)
|
||||||
#set(LYX_USE_TR1_REGEX 1) #TODO should we use it in ECMAScript mode?
|
#set(LYX_USE_TR1_REGEX 1) #TODO should we use it in ECMAScript mode?
|
||||||
|
else()
|
||||||
|
set(STD_STRING_USES_COW 1)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -297,6 +297,7 @@ if test x$GXX = xyes; then
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
AC_DEFINE(STD_STRING_USES_COW, 1, [std::string uses copy-on-write])
|
||||||
fi
|
fi
|
||||||
test "$lyx_pch_comp" = yes && lyx_flags="$lyx_flags pch"
|
test "$lyx_pch_comp" = yes && lyx_flags="$lyx_flags pch"
|
||||||
AM_CONDITIONAL(LYX_BUILD_PCH, test "$lyx_pch_comp" = yes)
|
AM_CONDITIONAL(LYX_BUILD_PCH, test "$lyx_pch_comp" = yes)
|
||||||
|
@ -101,6 +101,8 @@ liblyxsupport_a_SOURCES = \
|
|||||||
Translator.h \
|
Translator.h \
|
||||||
Timeout.cpp \
|
Timeout.cpp \
|
||||||
Timeout.h \
|
Timeout.h \
|
||||||
|
trivstring.cpp \
|
||||||
|
trivstring.h \
|
||||||
types.h \
|
types.h \
|
||||||
userinfo.cpp \
|
userinfo.cpp \
|
||||||
userinfo.h \
|
userinfo.h \
|
||||||
@ -143,18 +145,21 @@ EXTRA_DIST += \
|
|||||||
tests/test_lstrings \
|
tests/test_lstrings \
|
||||||
tests/regfiles/convert \
|
tests/regfiles/convert \
|
||||||
tests/regfiles/filetools \
|
tests/regfiles/filetools \
|
||||||
tests/regfiles/lstrings
|
tests/regfiles/lstrings \
|
||||||
|
tests/regfiles/trivstring
|
||||||
|
|
||||||
|
|
||||||
TESTS = \
|
TESTS = \
|
||||||
tests/test_convert \
|
tests/test_convert \
|
||||||
tests/test_filetools \
|
tests/test_filetools \
|
||||||
tests/test_lstrings
|
tests/test_lstrings \
|
||||||
|
tests/test_trivstring
|
||||||
|
|
||||||
check_PROGRAMS = \
|
check_PROGRAMS = \
|
||||||
check_convert \
|
check_convert \
|
||||||
check_filetools \
|
check_filetools \
|
||||||
check_lstrings
|
check_lstrings \
|
||||||
|
check_trivstring
|
||||||
|
|
||||||
if INSTALL_MACOSX
|
if INSTALL_MACOSX
|
||||||
ADD_FRAMEWORKS = -framework QtGui -framework QtCore -framework AppKit -framework ApplicationServices
|
ADD_FRAMEWORKS = -framework QtGui -framework QtCore -framework AppKit -framework ApplicationServices
|
||||||
@ -181,6 +186,13 @@ check_lstrings_SOURCES = \
|
|||||||
tests/dummy_functions.cpp \
|
tests/dummy_functions.cpp \
|
||||||
tests/boost.cpp
|
tests/boost.cpp
|
||||||
|
|
||||||
|
check_trivstring_LDADD = liblyxsupport.a $(LIBICONV) $(BOOST_LIBS) $(QT_CORE_LIBS) $(LIBSHLWAPI) @LIBS@
|
||||||
|
check_trivstring_LDFLAGS = $(QT_CORE_LDFLAGS) $(ADD_FRAMEWORKS)
|
||||||
|
check_trivstring_SOURCES = \
|
||||||
|
tests/check_trivstring.cpp \
|
||||||
|
tests/dummy_functions.cpp \
|
||||||
|
tests/boost.cpp
|
||||||
|
|
||||||
makeregfiles: ${check_PROGRAMS}
|
makeregfiles: ${check_PROGRAMS}
|
||||||
for all in ${check_PROGRAMS} ; do \
|
for all in ${check_PROGRAMS} ; do \
|
||||||
./$$all > ${srcdir}/tests/regfiles/$$all ; \
|
./$$all > ${srcdir}/tests/regfiles/$$all ; \
|
||||||
|
@ -95,6 +95,15 @@ std::string const & empty_string();
|
|||||||
// defined in docstring.cpp
|
// defined in docstring.cpp
|
||||||
bool operator==(docstring const &, char const *);
|
bool operator==(docstring const &, char const *);
|
||||||
|
|
||||||
|
#ifdef STD_STRING_USES_COW
|
||||||
|
template<typename Char> class trivial_string;
|
||||||
|
typedef trivial_string<char> trivstring;
|
||||||
|
typedef trivial_string<char_type> trivdocstring;
|
||||||
|
#else
|
||||||
|
typedef std::string trivstring;
|
||||||
|
typedef docstring trivdocstring;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,7 +28,7 @@ include_directories(
|
|||||||
${ZLIB_INCLUDE_DIR})
|
${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
|
|
||||||
set(check_PROGRAMS check_convert check_filetools check_lstrings)
|
set(check_PROGRAMS check_convert check_filetools check_lstrings check_trivstring)
|
||||||
|
|
||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/regfiles")
|
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/regfiles")
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include "../trivstring.h"
|
#include "../trivstring.h"
|
||||||
|
#include "../docstring.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -27,22 +28,111 @@ void test_trivstring()
|
|||||||
// assignment from trivstring
|
// assignment from trivstring
|
||||||
trivstring const c = a;
|
trivstring const c = a;
|
||||||
// assignment from std::string
|
// assignment from std::string
|
||||||
trivstring const d = input[i];
|
trivstring d = input[i];
|
||||||
// assignment from trivstring
|
// assignment from trivstring
|
||||||
string const e = a.str();
|
string const e = a;
|
||||||
// assignment from trivstring via C string
|
// assignment from trivstring via C string
|
||||||
string const f = a.c_str();
|
string const f = a.c_str();
|
||||||
|
if (a.empty())
|
||||||
|
cout << "empty ";
|
||||||
|
else
|
||||||
|
cout << "not empty ";
|
||||||
cout << a.length() << endl;
|
cout << a.length() << endl;
|
||||||
cout << a.str() << endl;
|
cout << a << endl;
|
||||||
cout << b.str() << endl;
|
cout << b << endl;
|
||||||
cout << c.str() << endl;
|
cout << c << endl;
|
||||||
cout << d.str() << endl;
|
cout << d << endl;
|
||||||
cout << e << endl;
|
cout << e << endl;
|
||||||
cout << f << endl;
|
cout << f << endl;
|
||||||
|
// swap
|
||||||
|
trivstring g("swap");
|
||||||
|
cout << g << endl;
|
||||||
|
d.swap(g);
|
||||||
|
cout << d << endl;
|
||||||
|
cout << g << endl;
|
||||||
}
|
}
|
||||||
|
// comparison
|
||||||
|
trivstring const a;
|
||||||
|
trivstring const b("a");
|
||||||
|
trivstring const c("b");
|
||||||
|
trivstring const d("42");
|
||||||
|
cout << (a == a) << ' ' << (a < a) << endl; // equal strings
|
||||||
|
cout << (a == b) << ' ' << (a < b) << endl; // different strings, same length
|
||||||
|
cout << (b == a) << ' ' << (b < a) << endl; // different strings, same length
|
||||||
|
cout << (a == c) << ' ' << (a < c) << endl; // different strings, different length
|
||||||
|
cout << (c == a) << ' ' << (c < a) << endl; // different strings, different length
|
||||||
|
char const * e = "";
|
||||||
|
char const * f = "b";
|
||||||
|
char const * g = "42";
|
||||||
|
cout << (a == e) << ' ' << (e == a) << endl; // empty strings
|
||||||
|
cout << (c == a) << ' ' << (a == c) << endl; // equal strings
|
||||||
|
cout << (a == f) << ' ' << (f == a) << endl; // different strings, same length
|
||||||
|
cout << (a == g) << ' ' << (g == a) << endl; // different strings, different length
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_trivdocstring()
|
||||||
|
{
|
||||||
|
docstring const input[] = {
|
||||||
|
from_ascii(""),
|
||||||
|
from_ascii("a"),
|
||||||
|
from_ascii("42"),
|
||||||
|
from_ascii("max"), // max. string with sso on 64 bit
|
||||||
|
from_ascii("something which does not fit into sso")
|
||||||
|
};
|
||||||
|
size_t const n = sizeof(input) / sizeof(input[0]);
|
||||||
|
for (size_t i = 0; i < n; ++i) {
|
||||||
|
// construction from std::string
|
||||||
|
trivdocstring const a(input[i]);
|
||||||
|
// construction from trivstring
|
||||||
|
trivdocstring const b(a);
|
||||||
|
// assignment from trivstring
|
||||||
|
trivdocstring const c = a;
|
||||||
|
// assignment from std::string
|
||||||
|
trivdocstring d = input[i];
|
||||||
|
// assignment from trivstring
|
||||||
|
docstring const e = a;
|
||||||
|
// assignment from trivstring via C string
|
||||||
|
docstring const f = a.c_str();
|
||||||
|
if (a.empty())
|
||||||
|
cout << "empty ";
|
||||||
|
else
|
||||||
|
cout << "not empty ";
|
||||||
|
cout << a.length() << endl;
|
||||||
|
cout << to_ascii(a) << endl;
|
||||||
|
cout << to_ascii(b) << endl;
|
||||||
|
cout << to_ascii(c) << endl;
|
||||||
|
cout << to_ascii(d) << endl;
|
||||||
|
cout << to_ascii(e) << endl;
|
||||||
|
cout << to_ascii(f) << endl;
|
||||||
|
// swap
|
||||||
|
trivdocstring g(from_ascii("swap"));
|
||||||
|
cout << to_ascii(g) << endl;
|
||||||
|
d.swap(g);
|
||||||
|
cout << to_ascii(d) << endl;
|
||||||
|
cout << to_ascii(g) << endl;
|
||||||
|
}
|
||||||
|
// comparison
|
||||||
|
trivdocstring const a;
|
||||||
|
trivdocstring const b(from_ascii("a"));
|
||||||
|
trivdocstring const c(from_ascii("b"));
|
||||||
|
trivdocstring const d(from_ascii("42"));
|
||||||
|
cout << (a == a) << ' ' << (a < a) << endl; // equal strings
|
||||||
|
cout << (a == b) << ' ' << (a < b) << endl; // different strings, same length
|
||||||
|
cout << (b == a) << ' ' << (b < a) << endl; // different strings, same length
|
||||||
|
cout << (a == c) << ' ' << (a < c) << endl; // different strings, different length
|
||||||
|
cout << (c == a) << ' ' << (c < a) << endl; // different strings, different length
|
||||||
|
// per character initialization works also if char_type != wchar
|
||||||
|
char_type const e[1] = {'\0'};
|
||||||
|
char_type const f[2] = {'b', '\0'};
|
||||||
|
char_type const g[3] = {'4', '2', '\0'};
|
||||||
|
cout << (a == e) << ' ' << (e == a) << endl; // empty strings
|
||||||
|
cout << (c == a) << ' ' << (a == c) << endl; // equal strings
|
||||||
|
cout << (a == f) << ' ' << (f == a) << endl; // different strings, same length
|
||||||
|
cout << (a == g) << ' ' << (g == a) << endl; // different strings, different length
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_trivstring();
|
test_trivstring();
|
||||||
|
test_trivdocstring();
|
||||||
}
|
}
|
||||||
|
@ -1,35 +1,118 @@
|
|||||||
0
|
empty 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
|
swap
|
||||||
|
swap
|
||||||
|
|
||||||
|
not empty 1
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
a
|
a
|
||||||
2
|
swap
|
||||||
|
swap
|
||||||
|
a
|
||||||
|
not empty 2
|
||||||
42
|
42
|
||||||
42
|
42
|
||||||
42
|
42
|
||||||
42
|
42
|
||||||
42
|
42
|
||||||
42
|
42
|
||||||
7
|
swap
|
||||||
|
swap
|
||||||
|
42
|
||||||
|
not empty 7
|
||||||
max sso
|
max sso
|
||||||
max sso
|
max sso
|
||||||
max sso
|
max sso
|
||||||
max sso
|
max sso
|
||||||
max sso
|
max sso
|
||||||
max sso
|
max sso
|
||||||
37
|
swap
|
||||||
|
swap
|
||||||
|
max sso
|
||||||
|
not empty 37
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
something which does not fit into sso
|
something which does not fit into sso
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
something which does not fit into sso
|
||||||
|
1 0
|
||||||
|
0 1
|
||||||
|
0 0
|
||||||
|
0 1
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
empty 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
|
||||||
|
not empty 1
|
||||||
|
a
|
||||||
|
a
|
||||||
|
a
|
||||||
|
a
|
||||||
|
a
|
||||||
|
a
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
a
|
||||||
|
not empty 2
|
||||||
|
42
|
||||||
|
42
|
||||||
|
42
|
||||||
|
42
|
||||||
|
42
|
||||||
|
42
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
42
|
||||||
|
not empty 3
|
||||||
|
max
|
||||||
|
max
|
||||||
|
max
|
||||||
|
max
|
||||||
|
max
|
||||||
|
max
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
max
|
||||||
|
not empty 37
|
||||||
|
something which does not fit into sso
|
||||||
|
something which does not fit into sso
|
||||||
|
something which does not fit into sso
|
||||||
|
something which does not fit into sso
|
||||||
|
something which does not fit into sso
|
||||||
|
something which does not fit into sso
|
||||||
|
swap
|
||||||
|
swap
|
||||||
|
something which does not fit into sso
|
||||||
|
1 0
|
||||||
|
0 1
|
||||||
|
0 0
|
||||||
|
0 1
|
||||||
|
0 0
|
||||||
|
1 1
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
0 0
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "support/trivstring.h"
|
#include "support/trivstring.h"
|
||||||
#include "support/docstring.h"
|
#include "support/docstring.h"
|
||||||
|
|
||||||
|
#ifdef STD_STRING_USES_COW
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -136,11 +137,10 @@ int trivial_string<Char>::compare(trivial_string const & other) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template string trivial_string<char>::str() const;
|
template trivial_string<char>::operator string() const;
|
||||||
template docstring trivial_string<char_type>::str() const;
|
template trivial_string<char_type>::operator docstring() const;
|
||||||
template<typename Char>
|
template<typename Char>
|
||||||
basic_string<Char, char_traits<Char>, allocator<Char> >
|
trivial_string<Char>::operator basic_string<Char, char_traits<Char>, allocator<Char> >() const
|
||||||
trivial_string<Char>::str() const
|
|
||||||
{
|
{
|
||||||
if (use_sso())
|
if (use_sso())
|
||||||
return basic_string<Char, char_traits<Char>, allocator<Char> >(
|
return basic_string<Char, char_traits<Char>, allocator<Char> >(
|
||||||
@ -172,9 +172,49 @@ template bool operator<(trivial_string<char> const &,
|
|||||||
template bool operator<(trivial_string<char_type> const &,
|
template bool operator<(trivial_string<char_type> const &,
|
||||||
trivial_string<char_type> const &);
|
trivial_string<char_type> const &);
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const &rhs)
|
bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
|
||||||
{
|
{
|
||||||
return lhs.compare(rhs) < 0;
|
return lhs.compare(rhs) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template bool operator==(trivial_string<char> const &,
|
||||||
|
trivial_string<char> const &);
|
||||||
|
template bool operator==(trivial_string<char_type> const &,
|
||||||
|
trivial_string<char_type> const &);
|
||||||
|
template <typename Char>
|
||||||
|
bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs)
|
||||||
|
{
|
||||||
|
return lhs.compare(rhs) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template bool operator==(trivial_string<char> const &, char const *);
|
||||||
|
template bool operator==(trivial_string<char_type> const &, char_type const *);
|
||||||
|
template <typename Char>
|
||||||
|
bool operator==(trivial_string<Char> const & lhs, Char const * rhs)
|
||||||
|
{
|
||||||
|
return lhs.compare(trivial_string<Char>(rhs)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template bool operator==(char const *, trivial_string<char> const &);
|
||||||
|
template bool operator==(char_type const *, trivial_string<char_type> const &);
|
||||||
|
template <typename Char>
|
||||||
|
bool operator==(Char const * lhs, trivial_string<Char> const & rhs)
|
||||||
|
{
|
||||||
|
return rhs.compare(trivial_string<Char>(lhs)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template ostream & operator<<(ostream &, trivial_string<char> const &);
|
||||||
|
template odocstream & operator<<(odocstream &, trivial_string<char_type> const &);
|
||||||
|
template <typename Char>
|
||||||
|
basic_ostream<Char, char_traits<Char> > &
|
||||||
|
operator<<(basic_ostream<Char, char_traits<Char> > & os, trivial_string<Char> const & s)
|
||||||
|
{
|
||||||
|
return os << basic_string<Char, char_traits<Char>, allocator<Char> >(s);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
|
#endif
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "support/strfwd.h"
|
#include "support/strfwd.h"
|
||||||
|
|
||||||
|
#ifdef STD_STRING_USES_COW
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace lyx {
|
namespace lyx {
|
||||||
@ -31,6 +32,9 @@ namespace lyx {
|
|||||||
* This class should not be used for anything else than providing thread-safety.
|
* This class should not be used for anything else than providing thread-safety.
|
||||||
* It should be removed as soon as LyX requires C++11, and all supported STL
|
* It should be removed as soon as LyX requires C++11, and all supported STL
|
||||||
* implementations provide a C++11 conformant std::basic_string.
|
* implementations provide a C++11 conformant std::basic_string.
|
||||||
|
*
|
||||||
|
* If you change anything in this class please ensure that the unit test
|
||||||
|
* tests/check_trivstring.cpp still tests 100% of the public interface.
|
||||||
*/
|
*/
|
||||||
template <typename Char> class trivial_string
|
template <typename Char> class trivial_string
|
||||||
{
|
{
|
||||||
@ -56,7 +60,7 @@ public:
|
|||||||
/// Is this string ordered before, at the same position or after \p other?
|
/// Is this string ordered before, at the same position or after \p other?
|
||||||
int compare(trivial_string const & other) const;
|
int compare(trivial_string const & other) const;
|
||||||
/// Create a copy as std::basic_string
|
/// Create a copy as std::basic_string
|
||||||
std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> > str() const;
|
operator std::basic_string<Char, std::char_traits<Char>, std::allocator<Char> >() const;
|
||||||
/// Return a C-compatible string, terminated by a 0 character.
|
/// Return a C-compatible string, terminated by a 0 character.
|
||||||
/// This is never a copy and only valid for the life time of the trivial_string instance.
|
/// This is never a copy and only valid for the life time of the trivial_string instance.
|
||||||
Char const * c_str() const;
|
Char const * c_str() const;
|
||||||
@ -80,8 +84,25 @@ private:
|
|||||||
/// The character storage
|
/// The character storage
|
||||||
Char * data_;
|
Char * data_;
|
||||||
};
|
};
|
||||||
template <typename Char> bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const &rhs);
|
|
||||||
|
|
||||||
|
|
||||||
|
/// Comparison operator (needed for std::set etc)
|
||||||
|
template <typename Char> bool operator<(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
|
||||||
|
|
||||||
|
|
||||||
|
/// Equality operator
|
||||||
|
template <typename Char> bool operator==(trivial_string<Char> const & lhs, trivial_string<Char> const & rhs);
|
||||||
|
template <typename Char> bool operator==(trivial_string<Char> const & lhs, Char const * rhs);
|
||||||
|
template <typename Char> bool operator==(Char const * lhs, trivial_string<Char> const & rhs);
|
||||||
|
|
||||||
|
|
||||||
|
/// Stream output operator
|
||||||
|
template <typename Char>
|
||||||
|
std::basic_ostream<Char, std::char_traits<Char> > &
|
||||||
|
operator<<(std::basic_ostream<Char, std::char_traits<Char> > &, trivial_string<Char> const &);
|
||||||
|
#else
|
||||||
|
#include <string>
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace lyx
|
} // namespace lyx
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user