From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- libcult/cult/types/string.hxx | 397 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 libcult/cult/types/string.hxx (limited to 'libcult/cult/types/string.hxx') diff --git a/libcult/cult/types/string.hxx b/libcult/cult/types/string.hxx new file mode 100644 index 0000000..108f830 --- /dev/null +++ b/libcult/cult/types/string.hxx @@ -0,0 +1,397 @@ +// file : cult/types/string.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Boris Kolpackov +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef CULT_TYPES_STRING_HXX +#define CULT_TYPES_STRING_HXX + +#include +#include + +//@@ Dependency on 'containers'. Maybe move iterator to 'types'? +// +#include + +#include +#include // mbstowcs + +namespace Cult +{ + namespace Types + { + //@@ Maybe create StringFwd.hxx + // + + namespace Bits + { + struct None {}; + + template + struct NarrowerChar + { + typedef None Type; + }; + + + template <> + struct NarrowerChar + { + typedef Char Type; + }; + } + + template ::Type> + class StringTemplate; + + template <> + class StringTemplate + { + }; + + + template + class StringTemplate : public std::basic_string + { + typedef std::basic_string Base; + typedef std::basic_string NarrowerBase; + + Base& + base () + { + return *this; + } + + Base const& + base () const + { + return *this; + } + + public: + typedef typename Base::value_type Value; + + /* + typedef traits traits_type; + typedef typename traits::char_type value_type; + typedef Allocator allocator_type; + typedef typename Allocator::size_type size_type; + typedef typename Allocator::difference_type difference_type; + typedef typename Allocator::reference reference; + typedef typename Allocator::const_reference const_reference; + typedef typename Allocator::pointer pointer; + typedef typename Allocator::const_pointer const_pointer; + */ + + typedef + Containers::IteratorAdapter + Iterator; + + typedef + Containers::IteratorAdapter + ConstIterator; + + + typedef + Containers::IteratorAdapter + ReverseIterator; + + typedef + Containers::IteratorAdapter + ConstReverseIterator; + + + using Base::npos; + using Base::empty; + + public: + explicit + StringTemplate () + { + } + + StringTemplate (StringTemplate const& str, Size pos, Size n = npos) + : Base (str, pos, n) + { + } + + StringTemplate (Value const* s, Size n) + : Base (s, n) + { + } + + StringTemplate (Value const* s) + : Base (s) + { + } + + StringTemplate (Size n, Value c) + : Base (n, c) + { + } + + template + StringTemplate(InputIterator begin, InputIterator end) + : Base (begin, end) + { + } + + StringTemplate (StringTemplate const& other) + : Base (other) + { + } + + // Conversion from Base. + // + StringTemplate (Base const& str) + : Base (str) + { + } + + // Conversion from the Narrower type. Experimental. + // + StringTemplate (NarrowerChar const* s) + { + from_narrow (s); + } + + StringTemplate (StringTemplate const& other) + { + from_narrow (other.c_str ()); + } + + StringTemplate (NarrowerBase const& other) + { + from_narrow (other.c_str ()); + } + + // Conversion to the Narrower type. Experimental. + // + struct NonRepresentable: virtual EH::Exception {}; + + StringTemplate + to_narrow () const; + + // Assignment. + // + StringTemplate& + operator= (StringTemplate const& str) + { + base () = str; + return *this; + } + + StringTemplate& + operator= (Value const* s) + { + base () = s; + return *this; + } + + StringTemplate& + operator= (Value c) + { + base () = c; + return *this; + } + + // Assignment from Base. + // + StringTemplate& + operator= (Base const& str) + { + base () = str; + return *this; + } + + public: + StringTemplate& + operator+= (StringTemplate const& str) + { + base () += str; + return *this; + } + + StringTemplate& + operator+= (Value const* s) + { + base () += s; + return *this; + } + + StringTemplate& + operator+= (Value c) + { + base () += c; + return *this; + } + + + public: + Iterator + begin () + { + return Iterator (base ().begin ()); + } + + Iterator + end () + { + return Iterator (base ().end ()); + } + + + ConstIterator + begin () const + { + return ConstIterator (base ().begin ()); + } + + ConstIterator + end () const + { + return ConstIterator (base ().end ()); + } + + // + // + + ReverseIterator + rbegin () + { + return ReverseIterator (base ().rbegin ()); + } + + ReverseIterator + rend () + { + return ReverseIterator (base ().rend ()); + } + + + ConstReverseIterator + rbegin () const + { + return ConstReverseIterator (base ().rbegin ()); + } + + ConstReverseIterator + rend () const + { + return ConstReverseIterator (base ().rend ()); + } + + + // Conversion to Boolean. + // + private: + typedef Void (StringTemplate::*BooleanConvertable)(); + + void + true_ () + { + } + + public: + operator BooleanConvertable () const + { + return empty () ? 0 : &StringTemplate::true_; + } + + private: + Void + from_narrow (NarrowerChar const* s); + }; + + + template + StringTemplate + operator+ (StringTemplate const& lhs, StringTemplate const& rhs) + { + return StringTemplate (lhs) += rhs; + } + + template + StringTemplate + operator+ (C const* lhs, StringTemplate const& rhs) + { + return StringTemplate (lhs) += rhs; + } + + template + StringTemplate + operator+ (StringTemplate const& lhs, C const* rhs) + { + return StringTemplate (lhs) += rhs; + } + + template + StringTemplate + operator+ (C lhs, StringTemplate const& rhs) + { + return StringTemplate (1, lhs) += rhs; + } + + + template + StringTemplate + operator+ (StringTemplate const& lhs, C rhs) + { + return StringTemplate (lhs) += rhs; + } + + // + // + typedef StringTemplate String; + typedef StringTemplate NarrowString; + typedef StringTemplate WideString; + + // Specialization for Char to WideChar conversion. + // + template <> + inline Void StringTemplate:: + from_narrow (Char const* s) + { + Size size (std::mbstowcs (0, s, 0) + 1); + + // I dare to change the guts! + // + resize (size - 1); + + WideChar* p (const_cast (data ())); + + std::mbstowcs (p, s, size); + } + + // Specialization for WideChar to Char conversion. + // + template <> + inline StringTemplate StringTemplate:: + to_narrow () const + { + Size size (std::wcstombs (0, c_str (), 0)); + + if (size == Size (-1)) + throw NonRepresentable (); + + // I dare to change the guts! + // + StringTemplate r; + r.resize (size); + + Char* p (const_cast (r.data ())); + + std::wcstombs (p, c_str (), size + 1); + + return r; + } + } + + using Types::String; + using Types::NarrowString; + using Types::WideString; + using Types::StringTemplate; +} + +#endif // CULT_TYPES_STRING_HXX -- cgit v1.2.3