Lars Gullik Bjønnes wrote:

> Georg Baum <[EMAIL PROTECTED]>
> writes:
> 
> | Am Montag, 14. August 2006 20:11 schrieb Lars Gullik Bjønnes:
> | > Ahh... that is what you have done.
> | > But we should not add the templates ourself I think. Only the explit
> | > specialization of the functions.
> | > 
> | > And we should make it be complete. (gut feeling...)
> | 
> | OK, I can do both, but you did not answer my question: Where should this
> | stuff go? .h or .C file? Which one?
> 
> .h file first. docstring.h.
> (Just to do it the same way libstdc++ does.)

This is not possible. We can either put templates in the .h file, or
specializations in a .C file.

Trying to put specializations into the .h file results in multiple
definitions of some methods. We can not do the same as modern libstdc++
does, because we have declarations in the old one:

        static void
        assign(char_type& __c1, const char_type& __c2);

and definitions in the new one:

        static void
        assign(char_type& __c1, const char_type& __c2)
        { __c1 = __c2; }

So we can either use templates in the .h file (x2.diff), or explicit
instantiations (x1.diff).

Which one shall I commit? I would prefer the header version, because it
avoids adding another file that would be empty for modern compilers.


Georg
Index: src/support/docstring.C
===================================================================
--- src/support/docstring.C	(Revision 0)
+++ src/support/docstring.C	(Revision 0)
@@ -0,0 +1,133 @@
+// -*- C++ -*-
+/**
+ * \file docstring.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * Provide a set of typedefs for commonly used things like sizes and
+ * indices wile trying to stay compatible with types used
+ * by the standard containers.
+ *
+ * \author Georg Baum
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include "docstring.h"
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 3 && __GNUC_MINOR__ < 4
+// Missing char_traits methods in gcc 3.3 and older. Taken from gcc 4.2svn.
+namespace std {
+
+template<> void
+char_traits<lyx::docstring::value_type>::assign(char_type & c1, char_type const & c2)
+{
+	c1 = c2;
+}
+
+
+template<> bool
+char_traits<lyx::docstring::value_type>::eq(char_type const & c1, char_type const & c2)
+{
+	return c1 == c2;
+}
+
+
+template<> bool
+char_traits<lyx::docstring::value_type>::lt(char_type const & c1, char_type const & c2)
+{
+	return c1 < c2;
+}
+
+
+template<> int
+char_traits<lyx::docstring::value_type>::compare(char_type const * s1, char_type const * s2, std::size_t n)
+{
+	for (std::size_t i = 0; i < n; ++i)
+		if (lt(s1[i], s2[i]))
+			return -1;
+		else if (lt(s2[i], s1[i]))
+			return 1;
+	return 0;
+}
+
+
+template<> std::size_t
+char_traits<lyx::docstring::value_type>::length(char_type const * p)
+{
+	std::size_t i = 0;
+	while (!eq(p[i], char_type()))
+		++i;
+	return i;
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::char_type const *
+char_traits<lyx::docstring::value_type>::find(char_type const * s, size_t n, char_type const & a)
+{
+	for (std::size_t i = 0; i < n; ++i)
+		if (eq(s[i], a))
+			return s + i;
+	return 0;
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::char_type *
+char_traits<lyx::docstring::value_type>::move(char_type * s1, char_type const * s2, std::size_t n)
+{
+	return static_cast<lyx::docstring::value_type *>(std::memmove(s1, s2, n * sizeof(char_type)));
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::char_type *
+char_traits<lyx::docstring::value_type>::copy(char_type * s1, char_type const * s2, std::size_t n)
+{
+	std::copy(s2, s2 + n, s1);
+	return s1;
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::char_type *
+char_traits<lyx::docstring::value_type>::assign(char_type * s, std::size_t n, char_type a)
+{
+	std::fill_n(s, n, a);
+	return s;
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::char_type
+char_traits<lyx::docstring::value_type>::to_char_type(int_type const & c)
+{
+	return static_cast<char_type>(c);
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::int_type
+char_traits<lyx::docstring::value_type>::to_int_type(char_type const & c)
+{
+	return static_cast<int_type>(c);
+}
+
+
+template<> bool
+char_traits<lyx::docstring::value_type>::eq_int_type(int_type const & c1, int_type const & c2)
+{
+	return c1 == c2;
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::int_type
+char_traits<lyx::docstring::value_type>::eof()
+{
+	return static_cast<int_type>(EOF);
+}
+
+
+template<> char_traits<lyx::docstring::value_type>::int_type
+char_traits<lyx::docstring::value_type>::not_eof(int_type const & c)
+{
+	return !eq_int_type(c, eof()) ? c : to_int_type(char_type());
+}
+
+}
+#endif
Index: src/support/fs_extras.C
===================================================================
--- src/support/fs_extras.C	(Revision 14683)
+++ src/support/fs_extras.C	(Arbeitskopie)
@@ -17,6 +17,7 @@
 #include <boost/filesystem/exception.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/throw_exception.hpp>
+#include <boost/version.hpp>
 
 #ifdef HAVE_SYS_TYPES_H
 # include <sys/types.h>
@@ -45,6 +46,22 @@ namespace fs = boost::filesystem;
 namespace boost {
 namespace filesystem {
 
+#if BOOST_VERSION >= 103400
+#include <cerrno>
+#define filesystem_error filesystem_path_error
+namespace detail {
+	fs::errno_type system_error_code()
+	{
+#ifdef BOOST_POSIX
+		return fs::lookup_errno(errno);
+#endif
+#ifdef BOOST_WINDOWS
+		return fs::detail::system_error_code(errno);
+#endif
+	}
+}
+#endif
+
 bool is_readable(path const & ph)
 {
 #ifdef BOOST_POSIX
Index: src/support/Makefile.am
===================================================================
--- src/support/Makefile.am	(Revision 14683)
+++ src/support/Makefile.am	(Arbeitskopie)
@@ -28,6 +28,7 @@ libsupport_la_SOURCES = \
 	cow_ptr.h \
 	debugstream.h \
 	docstring.h \
+	docstring.C \
 	environment.h \
 	environment.C \
 	filefilterlist.C \
Index: src/support/docstring.h
===================================================================
--- src/support/docstring.h	(Revision 14683)
+++ src/support/docstring.h	(Arbeitskopie)
@@ -25,4 +25,121 @@ typedef std::basic_string<boost::uint32_
 
 }
 
+
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 3 && __GNUC_MINOR__ < 4
+// Missing char_traits methods in gcc 3.3 and older. Taken from gcc 4.2svn.
+namespace std {
+
+template<typename T> void
+char_traits<T>::assign(char_type & c1, char_type const & c2)
+{
+	c1 = c2;
+}
+
+
+template<typename T> bool
+char_traits<T>::eq(char_type const & c1, char_type const & c2)
+{
+	return c1 == c2;
+}
+
+
+template<typename T> bool
+char_traits<T>::lt(char_type const & c1, char_type const & c2)
+{
+	return c1 < c2;
+}
+
+
+template<typename T> int
+char_traits<T>::compare(char_type const * s1, char_type const * s2, std::size_t n)
+{
+	for (std::size_t i = 0; i < n; ++i)
+		if (lt(s1[i], s2[i]))
+			return -1;
+		else if (lt(s2[i], s1[i]))
+			return 1;
+	return 0;
+}
+
+
+template<typename T> std::size_t
+char_traits<T>::length(char_type const * p)
+{
+	std::size_t i = 0;
+	while (!eq(p[i], char_type()))
+		++i;
+	return i;
+}
+
+
+template<typename T> typename char_traits<T>::char_type const *
+char_traits<T>::find(char_type const * s, size_t n, char_type const & a)
+{
+	for (std::size_t i = 0; i < n; ++i)
+		if (eq(s[i], a))
+			return s + i;
+	return 0;
+}
+
+
+template<typename T> typename char_traits<T>::char_type *
+char_traits<T>::move(char_type * s1, char_type const * s2, std::size_t n)
+{
+	return static_cast<T *>(std::memmove(s1, s2, n * sizeof(char_type)));
+}
+
+
+template<typename T> typename char_traits<T>::char_type *
+char_traits<T>::copy(char_type * s1, char_type const * s2, std::size_t n)
+{
+	std::copy(s2, s2 + n, s1);
+	return s1;
+}
+
+
+template<typename T> typename char_traits<T>::char_type *
+char_traits<T>::assign(char_type * s, std::size_t n, char_type a)
+{
+	std::fill_n(s, n, a);
+	return s;
+}
+
+
+template<typename T> typename char_traits<T>::char_type
+char_traits<T>::to_char_type(int_type const & c)
+{
+	return static_cast<char_type>(c);
+}
+
+
+template<typename T> typename char_traits<T>::int_type
+char_traits<T>::to_int_type(char_type const & c)
+{
+	return static_cast<int_type>(c);
+}
+
+
+template<typename T> bool
+char_traits<T>::eq_int_type(int_type const & c1, int_type const & c2)
+{
+	return c1 == c2;
+}
+
+
+template<typename T> typename char_traits<T>::int_type
+char_traits<T>::eof()
+{
+	return static_cast<int_type>(EOF);
+}
+
+
+template<typename T> typename char_traits<T>::int_type
+char_traits<T>::not_eof(int_type const & c)
+{
+	return !eq_int_type(c, eof()) ? c : to_int_type(char_type());
+}
+
+}
+#endif
 #endif

Reply via email to