Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.4.0)

E90870-01

coherence/lang/String.hpp

00001 /*
00002 * String.hpp
00003 *
00004 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_STRING_HPP
00017 #define COH_STRING_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Array.hpp"
00022 #include "coherence/lang/Comparable.hpp"
00023 #include "coherence/lang/Object.hpp"
00024 
00025 #include <memory>
00026 
00027 #include <sstream>
00028 #include <string>
00029 
00030 COH_OPEN_NAMESPACE2(coherence,lang)
00031 
00032 /**
00033 * @internal
00034 *
00035 * Used to protect protected inheritance of Array<octet_t> by String, as
00036 * spec based class definitions don't have a notion of protected
00037 * inheritance.
00038 */
00039 class COH_EXPORT_SPEC ProtectedOctetArray
00040     : protected Array<octet_t>
00041     {
00042     public:
00043         typedef Array<octet_t>::super super;
00044         typedef Array<octet_t>::alias alias;
00045 
00046     protected:
00047         ProtectedOctetArray(size32_t cb, octet_t* ab)
00048             : Array<octet_t>(cb, ab)
00049             {}
00050 
00051         ProtectedOctetArray(ProtectedOctetArray::View vThat,
00052             size32_t iFrom, size32_t iTo)
00053             : Array<octet_t>(vThat, iFrom, iTo)
00054             {}
00055 
00056         virtual ~ProtectedOctetArray()
00057             {}
00058     };
00059 
00060 
00061 /**
00062 * A managed C-style (NUL terminated) string.
00063 *
00064 * In addition to exposing the underlying char array, the String class
00065 * supports transformations to and from Unicode code points within the Basic
00066 * Multilingual Plane (BMP):
00067 *
00068 * <ul>
00069 * <li>UTF-8  BMP char array</li>
00070 * <li>UTF-16 BMP wchar_t array (on platforms where wchar_t is >= 16 bits)</li>
00071 * <li>UTF-8  BMP octet_t array</li>
00072 * <li>UTF-16 BMP wchar16_t array</li>
00073 * </ul>
00074 *
00075 * Note: the ASCII character set is a subset of UTF-8 BMP.
00076 *
00077 * Unlike most managed types in the Coherence class hierarchy, Strings are
00078 * auto-boxable by default. That is a String::Handle or String::View can be
00079 * directly assigned from or to common string representations.  For example
00080 * the following code is legal:
00081 * @code
00082 * String::Handle hs = "hello world";
00083 * @endcode
00084 * as is
00085 * @code
00086 * void someFunction(String::View vs);
00087 *
00088 * someFunction("some value");
00089 * @endcode
00090 *
00091 * @see StringHandle for details
00092 *
00093 * @author mf/jh/djl  2007.07.05
00094 */
00095 class COH_EXPORT String
00096     : public cloneable_spec<String,
00097         extends<ProtectedOctetArray>,
00098         implements<Comparable> >
00099     {
00100     friend class factory<String>;
00101 
00102     // ----- constants ------------------------------------------------------
00103 
00104     public:
00105         /**
00106         * The largest possible value of type size32_t.
00107         */
00108         static const size32_t npos = size32_t(-1);
00109 
00110 
00111     // ----- typedefs -------------------------------------------------------
00112 
00113     public:
00114         /**
00115         * While StringHandle boxes a number of common string types, String is
00116         * still compatible with BoxHandle, and when used with it can box to
00117         * only one type. By default Strings are boxable from a number of
00118         * types, see StringHandle for details.
00119         */
00120         typedef std::string BoxedType;
00121 
00122 
00123     // ----- nested class: StringHandle -------------------------------------
00124 
00125     public:
00126         /**
00127         * StringHandle provides standard TypedHandle features as well as
00128         * auto-boxing support for standard string types including:
00129         *
00130         * <ul>
00131         * <li>char[]       C-style NUL terminated char array</li>
00132         * <li>std::string  STL string</li>
00133         * <li>std::wstring STL wide string</li>
00134         * </ul>
00135         *
00136         * Boxing from wchar_t[] is supported, but requires an explicit
00137         * constructor call in order to avoid ambiguity when assigning a
00138         * String handle/view to NULL.
00139         *
00140         * Unboxing to char[] and wchar[] is not supported as it is unsafe to
00141         * maintain a reference to the underlying character array without
00142         * holding a reference to the String. Unboxing to std::string, and
00143         * std::wstring is both supported and safe.
00144         */
00145         template<class T> class StringHandle
00146             : public TypedHandle<T>
00147             {
00148             // ----- constructors ---------------------------------------
00149 
00150             public:
00151                 /**
00152                 * Create an empty StringHandle.
00153                 */
00154                 StringHandle()
00155                     : TypedHandle<T>()
00156                     {
00157                     }
00158 
00159                 /**
00160                 * Create a new StringHandle from a boxable type.
00161                 */
00162                 StringHandle(const char* ach)
00163                     : TypedHandle<T>()
00164                     {
00165                     if (NULL != ach)
00166                         {
00167                         TypedHandle<T>::operator=(T::create(ach));
00168                         }
00169                     }
00170 
00171                 /**
00172                 * Create a new StringHandle from a boxable type.
00173                 */
00174                 explicit StringHandle(const wchar_t* ach)
00175                     : TypedHandle<T>()
00176                     {
00177                     if (NULL != ach)
00178                         {
00179                         TypedHandle<T>::operator=(T::create(ach));
00180                         }
00181                     }
00182 
00183                 /**
00184                 * Create a new StringHandle from a boxable type.
00185                 */
00186                 template<class C, class R, class A> COH_INLINE
00187                 StringHandle(const std::basic_string<C, R, A>& s)
00188                     : TypedHandle<T>(T::create(s))
00189                     {
00190                     }
00191 
00192                 /**
00193                 * Create a new StringHandle from the TypedHandle with a type
00194                 * conversion.
00195                 */
00196                 template<class O> StringHandle<T>(const TypedHandle<O>& that)
00197                     : TypedHandle<T>(that)
00198                     {
00199                     }
00200 
00201                 /**
00202                 * The copy constructor.
00203                 */
00204                 StringHandle(const StringHandle& that)
00205                     : TypedHandle<T>(that)
00206                     {
00207                     }
00208 
00209                 /**
00210                 * Create a new StringHandle from the raw pointer.
00211                 */
00212                 explicit StringHandle(T* o)
00213                     : TypedHandle<T>(o)
00214                     {
00215                     }
00216 
00217             // ----- operators ------------------------------------------
00218 
00219             public:
00220                 /**
00221                 * The assignment operator.
00222                 */
00223                 template<class O>
00224                 StringHandle& operator=(const TypedHandle<O>& that)
00225                     {
00226                     TypedHandle<T>::operator=(that);
00227                     return *this;
00228                     }
00229 
00230                 /**
00231                 * The "boxing" operator.
00232                 */
00233                 StringHandle& operator=(const char* ach)
00234                     {
00235                     if (NULL == ach)
00236                         {
00237                         TypedHandle<T>::operator=(NULL);
00238                         }
00239                     else
00240                         {
00241                         TypedHandle<T>::operator=(T::create(ach));
00242                         }
00243                     return *this;
00244                     }
00245 
00246                 /**
00247                 * The "boxing" operator.
00248                 */
00249                 template<class C, class R, class A> COH_INLINE
00250                 StringHandle& operator=(const std::basic_string<C, R, A>& s)
00251                     {
00252                     TypedHandle<T>::operator=(T::create(s));
00253                     return *this;
00254                     }
00255 
00256                 /**
00257                 * The "unboxing" operator.
00258                 *
00259                 * @return a copy of the referenced Object
00260                 */
00261                 template<class C, class R, class A> COH_INLINE
00262                 operator std::basic_string<C, R, A>() const
00263                     {
00264                     const T* pT = TypedHandle<T>::get();
00265                     if (NULL == pT)
00266                         {
00267                         coh_throw_npe(typeid(T));
00268                         }
00269                     return (std::basic_string<C, R, A>) *pT;
00270                     }
00271             };
00272 
00273     // ----- handle definitions ---------------------------------------------
00274 
00275     public:
00276         /**
00277         * Handle definition.
00278         */
00279         typedef StringHandle<String> Handle;
00280 
00281         /**
00282         * View definition.
00283         */
00284         typedef StringHandle<const String> View;
00285 
00286 
00287     // ----- factory methods ------------------------------------------------
00288 
00289     public:
00290         /**
00291         * Create a String from a C-style NUL terminated char array.
00292         *
00293         * @param ach  the NUL terminated string of chars to copy
00294         * @param cch  the number of chars to copy; if npos, until NUL
00295         *
00296         * @throws IllegalArgumentException if any of the elements in the
00297         *         array are not UTF-8 BMP
00298         */
00299         static String::Handle create(const char* achSrc = "", size32_t cch = npos);
00300 
00301         /**
00302         * Create a String from a C-style NUL terminated wide char array.
00303         *
00304         * @param ach  the NUL terminated string of wide chars to copy
00305         * @param cch  the number of chars to copy; if npos, copy until NUL
00306         *
00307         * @throws IllegalArgumentException if any of the elements in the
00308         *         array are not UTF-16 BMP
00309         */
00310         static String::Handle create(const wchar_t* achSrc, size32_t cch = npos);
00311 
00312         /**
00313         * Create a String from an STL string.
00314         *
00315         * @param s  the STL string to copy
00316         *
00317         * @throws IllegalArgumentException if any of the elements in the
00318         *         array are not UTF-8 BMP
00319         */
00320         template<class C, class R, class A> static COH_INLINE
00321             String::Handle create(const std::basic_string<C, R, A>& s)
00322             {
00323             size_t cch = s.size();
00324             if (cch >= npos) // for 64b
00325                 {
00326                 coh_throw_illegal_argument("maximum String length exceeded");
00327                 }
00328             return String::create(s.data(), size32_t(cch));
00329             }
00330 
00331         /**
00332         * Create a String from a char array.
00333         *
00334         * @param vach  the array of chars to copy
00335         * @param of    the offset at which to start copying
00336         * @param cch   the number of chars to copy; if npos, copy all
00337         *              subsequent chars in the array
00338         *
00339         * @throws IndexOutOfBoundsException if of > vach->length or if
00340         *         cch < npos and of + cch > vach->length
00341         * @throws IllegalArgumentException if any of the elements in the
00342         *         array are not UTF-8 BMP
00343         */
00344         static String::Handle create(Array<char>::View vachSrc,
00345                 size32_t of = 0, size32_t cch = npos);
00346 
00347         /**
00348         * Create a String from a wide char array.
00349         *
00350         * @param vach  the array of chars to copy
00351         * @param of    the offset at which to start copying
00352         * @param cch   the number of chars to copy; if npos, copy all
00353         *              subsequent chars in the array
00354         *
00355         * @throws IndexOutOfBoundsException if of > vach->length or if
00356         *         cch < npos and of + cch > vach->length
00357         * @throws IllegalArgumentException if any of the elements in the
00358         *         array are not UTF-16 BMP
00359         * @throws UnsupportedOperationException if sizeof(wchar_t) <
00360         *         sizeof(wchar16_t)
00361         */
00362         static String::Handle create(Array<wchar_t>::View vachSrc,
00363                 size32_t of = 0, size32_t cch = npos);
00364 
00365         /**
00366         * Create a String from an octet array.
00367         *
00368         * @param vab  the array of octets to copy
00369         * @param of   the offset at which to start copying
00370         * @param cb   the number of octets to copy; if npos, copy all
00371         *             subsequent octets in the array
00372         *
00373         * @throws IndexOutOfBoundsException if of > vab->length or if
00374         *         cb < npos and of + cb > vab->length
00375         * @throws IllegalArgumentException if any of the elements in the
00376         *         array are not UTF-8 BMP
00377         */
00378         static String::Handle create(Array<octet_t>::View vabSrc,
00379                 size32_t of = 0, size32_t cb = npos);
00380 
00381         /**
00382         * Create a String from a 16-bit char array.
00383         *
00384         * @param vach  the array of chars to copy
00385         * @param of    the offset at which to start copying
00386         * @param cch   the number of chars to copy; if npos, copy all
00387         *              subsequent chars in the array
00388         *
00389         * @throws IndexOutOfBoundsException if of > vach->length or if
00390         *         cch < npos and of + cch > vach->length
00391         * @throws IllegalArgumentException if any of the elements in the
00392         *         array are not UTF-16 BMP
00393         */
00394         static String::Handle create(Array<wchar16_t>::View vachSrc,
00395                 size32_t of = 0, size32_t cch = npos);
00396 
00397         /**
00398         * Create a String from another String.
00399         *
00400         * Needed for clone().
00401         *
00402         * @param that  the String to copy
00403         *
00404         * @since Coherence 3.7.1.8
00405         */
00406         static String::Handle create(const String& that);
00407 
00408 
00409     // ----- constructors ---------------------------------------------------
00410 
00411     private:
00412         /**
00413         * Constructor.
00414         *
00415         * @param ccp  the number of code points in the string
00416         * @param cb   the number of octets in the string
00417         * @param ab   the String's octets
00418         * @param fCs  true if ab represents a c string
00419         */
00420         String(size32_t ccp, size32_t cb, octet_t* ab, bool fCs);
00421 
00422         /**
00423         * Copy constructor.
00424         */
00425         String(const String& that);
00426 
00427 
00428     // ----- String interface -----------------------------------------------
00429 
00430     public:
00431         /**
00432         * Return true iff the String contains only ASCII (ISO-8859-1)
00433         * characters. In this case each character is represented by a single
00434         * char, otherwise a character can take between one and three chars.
00435         *
00436         * @return true iff the String contains only ASCII characters
00437         */
00438         virtual bool isASCII() const;
00439 
00440         /**
00441          * Return true if the String is ASCII and does not contain embedded nuls.
00442          *
00443          * @return true if the String is a C string.
00444          */
00445         virtual bool isCString() const;
00446 
00447         /**
00448         * Return the number of unicode code points (characters) in this String.
00449         *
00450         * @return the number of characters in this String
00451         */
00452         virtual size32_t length() const;
00453 
00454         /**
00455          * Returns true if, and only if, length() is 0.
00456          *
00457          * @return true if length() is 0, otherwise false
00458          *
00459          * @since 12.2.1
00460          */
00461         virtual bool isEmpty() const;
00462 
00463         /**
00464         * Return the String as a C-style NUL terminated char array.
00465         *
00466         * If the String is non-ASCII then the String::next() method may be
00467         * used to expand the char array into a sequence of wchar16_t unicode
00468         * characters.
00469         *
00470         * The returned array's lifetime is bound to the lifetime of the
00471         * String which it was returned from. Specifically it is unsafe to use
00472         * the returned char* while not holding a handle to the String.
00473         *
00474         * @return the char array representing the String.
00475         */
00476         virtual const char* getCString() const;
00477 
00478         /**
00479         * Compare this String against the supplied C-style string.
00480         *
00481         * @param ach  the NUL terminated C-style string to compare to this
00482         *             String
00483         * @param cch  the length of the supplied string, or npos to rely on
00484         *             NUL terminator
00485         *
00486         * @return true iff the two strings are identical
00487         */
00488         virtual bool equals(const char* ach, size32_t cch = npos) const;
00489 
00490         /**
00491         * Compare this String against the supplied C-style wide char string.
00492         *
00493         * @param ach  the NUL terminated C-style string to compare to this
00494         *             String
00495         * @param cch  the length of the supplied string, or npos to rely on
00496         *             NUL terminator
00497         *
00498         * @return true iff the two strings are identical
00499         *
00500         * @throws UnsupportedOperationException if sizeof(wchar_t) < sizeof(wchar16_t)
00501         */
00502         virtual bool equals(const wchar_t* ach, size32_t cch = npos) const;
00503 
00504         /**
00505         * Compare this String against the supplied STL string or wstring.
00506         *
00507         * @param s  the STL string to compare to this String
00508         *
00509         * @return true iff the two strings are identical
00510         */
00511         template<class C, class R, class A> COH_INLINE
00512             bool equalsStd(const std::basic_string<C, R, A>& s) const
00513             {
00514             size_t cch = s.size();
00515             return cch < npos && equals(s.data(), size32_t(cch));
00516             }
00517 
00518         /**
00519         * Convert the String to any of the types supported by StringHandle,
00520         * namely an STL string or wstring.
00521         *
00522         * @return the std::string/wstring representation
00523         */
00524         template<class C, class R, class A> COH_INLINE
00525             operator std::basic_string<C, R, A>() const
00526             {
00527             if (sizeof(C) == sizeof(octet_t))
00528                 {
00529                 return std::basic_string<C, R, A>((const C*) getCString(),
00530                         super::length - 1);
00531                 }
00532 
00533             if (sizeof(C) < sizeof(wchar16_t))
00534                 {
00535                 coh_throw_unsupported_operation("unsupported string type");
00536                 }
00537 
00538             typename std::basic_string<C, R, A>::size_type cch =
00539                 typename std::basic_string<C, R, A>::size_type(length());
00540             const char* iter = getCString();
00541             std::basic_string<C, R, A> ws;
00542             ws.reserve(cch);
00543             for (typename std::basic_string<C, R, A>::size_type
00544                     i = 0; i < cch; ++i)
00545                 {
00546                 ws.push_back((C) String::next(iter));
00547                 }
00548             return ws;
00549             }
00550 
00551         /**
00552         * Return the index of a substring within this String.
00553         *
00554         * @param vsSearch  the substring to search for in vsSource
00555         * @param iBegin    the location in the string to start searching
00556         *
00557         * @return the index of the substring found within this String or npos
00558         */
00559         virtual size32_t indexOf(String::View vsSearch,
00560                 size32_t iBegin = 0) const;
00561 
00562         /**
00563         * Return the index of a character within this String.
00564         *
00565         * @param chSearch  the character to search for in this String
00566         * @param iBegin    the location in this String to start searching
00567         *
00568         * @return the index of the character found within this String or npos
00569         */
00570         virtual size32_t indexOf(wchar16_t chSearch,
00571                 size32_t iBegin = 0) const;
00572 
00573         /**
00574         * Return the index of a substring within this String by searching
00575         * backward from the given beginning index.
00576         *
00577         * @param vsSearh  the substring to search for within this String
00578         * @param iBegin   the location in this String to start searching
00579         *
00580         * @return the index of the substring found within this String or npos
00581         */
00582         virtual size32_t lastIndexOf(String::View vsSearch,
00583                 size32_t iBegin = npos) const;
00584 
00585         /**
00586         * Return the index of a substring within this String by searching
00587         * backward from the given beginning index.
00588         *
00589         * @param chSearch  the character to search for in this String
00590         * @param iBegin    the location in this String to start searching
00591         *
00592         * @return the index of the character found within this String or npos
00593         */
00594         virtual size32_t lastIndexOf(wchar16_t chSearch,
00595                 size32_t iBegin = npos) const;
00596 
00597         /**
00598         * Return a new String that is a substring of this string. The substring
00599         * begins at the specified iBegin and extends to the character at
00600         * index iEnd - 1.  Thus the length of the substring is iEnd-iBegin.
00601         *
00602         * @param iBegin    the starting index from which to create the string
00603         * @param iEnd      the index of where the substring should stop
00604         *                  in this String or npos for end of string
00605         *
00606         * @throws IndexOutOfBoundsException  if iEnd is larger than the length 
00607         *                                    of this String object, or if iBegin
00608         *                                    is larger than iEnd.
00609         *
00610         * @return the new substring created from this String
00611         */
00612         virtual String::View substring(size32_t iBegin,
00613                 size32_t iEnd = npos) const;
00614 
00615         /**
00616         * Return true if this String starts with the supplied String.
00617         *
00618         * @param vsSearch  the string to search for
00619         *
00620         * @return true if this String starts with vsSearch
00621         */
00622         virtual bool startsWith(String::View vsSearch) const;
00623 
00624         /**
00625         * Return true if this String ends with the supplied String.
00626         *
00627         * @param vsSearch  the string to search for
00628         *
00629         * @return true if this String ends with vsSearch
00630         */
00631         virtual bool endsWith(String::View vsSearch) const;
00632 
00633         /**
00634         * A substring of this String is compared to a substring of a supplied
00635         * String.
00636         *
00637         * @param ofSource  the offset in this String where comparison begins
00638         * @param vsOther   the String whose substring is compared against
00639         *                  this String
00640         * @param ofOther   the offset in vsOther where comparison begins
00641         * @param cch       the count of characters to compare, or npos for
00642         *                  (vsOther->length - ofOther)
00643         *
00644         * @return the result of the two substrings
00645         */
00646         virtual bool regionMatches(size32_t ofSourse,
00647                 String::View vsOther, size32_t ofOther = 0,
00648                 size32_t cch = npos) const;
00649 
00650         /**
00651         * Return a String that is the result of removing all leading and
00652         * trailing white space.
00653         *
00654         * @return a trimmed copy of this String
00655         */
00656         String::View trim() const;
00657 
00658         /**
00659         * Return the underlying UTF-8 BMP NUL terminated Array<octet_t>.
00660         *
00661         * For performance reasons the returned Array may not support cloning.
00662         * If clone() is called the result will a String, which depending on
00663         * the compiler's handling of dynamic_cast to a private super class may
00664         * fail to be castable to an Array<octet_t>.
00665         *
00666         * @return the Array<octet_t>
00667         */
00668         virtual Array<octet_t>::View getOctets() const;
00669 
00670     // ----- static methods -------------------------------------------------
00671 
00672     public:
00673         /**
00674          * Returns the string representation of the {@code v} argument.
00675          *
00676          * @param   v  an Object.
00677          *
00678          * @return  if the argument is {@code NULL}, then a string equal to
00679          *          {@code "NULL"}; otherwise, the value of
00680          *          {@code v->toString()} is returned
00681          *
00682          * @see     Object#toString()
00683          *
00684          * @since 12.2.1
00685          */
00686         static String::View valueOf(Object::View v);
00687 
00688     // ----- Array interface ------------------------------------------------
00689 
00690     protected:
00691         using Array<octet_t>::regionMatches;
00692 
00693 
00694     // ----- Comparable interface -------------------------------------------
00695 
00696     public:
00697         /**
00698         * {@inheritDoc}
00699         */
00700         virtual int32_t compareTo(Object::View v) const;
00701 
00702 
00703     // ----- Object interface -----------------------------------------------
00704 
00705     public:
00706         /**
00707         * {@inheritDoc}
00708         */
00709         virtual size32_t hashCode() const;
00710 
00711         /**
00712         * {@inheritDoc}
00713         */
00714         virtual TypedHandle<const String> toString() const;
00715 
00716         /**
00717         * {@inheritDoc}
00718         */
00719         virtual bool isImmutable() const;
00720 
00721         /**
00722         * {@inheritDoc}
00723         */
00724         virtual bool equals(Object::View v) const;
00725 
00726         /**
00727         * {@inheritDoc}
00728         */
00729         virtual size64_t sizeOf(bool fDeep = false) const;
00730 
00731     // ----- static helpers -------------------------------------------------
00732 
00733     public:
00734         /**
00735         * Return the Unicode character as UTF-16 from the char array, and
00736         * increment the pointer such that it references the start of the
00737         * next Unicode character.
00738         *
00739         * @param ach  pointer to the start of the next UTF-8 code point.
00740         *
00741         * @return the next Unicode character
00742         *
00743         * @throws IllegalArgumentException  if a non UTF-8 BMP sequence is
00744         *                                   encountered
00745         */
00746         static wchar16_t next(const char*& ach);
00747 
00748 
00749     // ----- data members ---------------------------------------------------
00750 
00751     protected:
00752         /**
00753         * The number of unicode code points (characters) in the String.
00754         */
00755         size32_t m_ccp;
00756 
00757         /**
00758          * True iff the String is a C string.
00759          */
00760         bool m_fCString;
00761 
00762 
00763     // ----- constants ------------------------------------------------------
00764 
00765     public:
00766         /**
00767         * String referencing NULL.
00768         *
00769         * This constant is generally only needed for defining a default
00770         * value for a function parameter:
00771         *
00772         * @code
00773         * void function(String::View vs = String::null_string)
00774         * @endcode
00775         *
00776         * Simply passing NULL as a default is not allowable for Strings as due
00777         * to auto-boxing the compiler is unable to determine if NULL indicates
00778         * a String* or a char*. For all other uses of NULL with String the
00779         * literal NULL is preferred.
00780         */
00781         static const char* const null_string;
00782     };
00783 
00784 
00785 // ----- non-member operators and functions ---------------------------------
00786 
00787 /**
00788 * Output a human-readable description of the specified Object to the given
00789 * stream.
00790 *
00791 * @param out  the stream used to output the description
00792 * @param o    the Object to describe
00793 *
00794 * @return the supplied stream
00795 */
00796 COH_INLINE std::ostream& operator<<(std::ostream& out, const Object& o)
00797     {
00798     // legacy support for deprecated toStream method, test if toStream or toString has been overridden
00799     // this is relatively expensive and will be removed in a future release when toStream is removed
00800     std::stringstream ss;
00801     o.toStream(ss); // no-op on Object
00802     if (ss.tellp() <= 0) // common case - on empty stream STLport returns -1; others return 0
00803         {
00804         // toStream has not been overridden, use toString
00805         String::View vs = o.toString(); // ensure String stays alive while working with the c string
00806         if (vs->isCString()) // NUL terminated ASCII
00807             {
00808             out << vs->getCString();
00809             }
00810         else if (vs->isASCII()) // ASCII with embedded NULs
00811             {
00812             const char* pch = vs->getCString();
00813             for (size32_t i = 0, c = vs->length(); i < c; ++i)
00814                 {
00815                 out << pch[i];
00816                 }
00817             }
00818         else // unicode, "inherit" however std::string outputs embedded unicode to an ostream
00819             {
00820             std::string s = vs;
00821             out << s;
00822             }
00823         }
00824     else // toStream wrote output (was overridden)
00825         {
00826         out << ss.str();
00827         }
00828     return out;
00829     }
00830 
00831 /**
00832 * Output a human-readable description of the specified Object to the given
00833 * stream.
00834 *
00835 * @param out  the stream used to output the description
00836 * @param o    the Object to describe
00837 *
00838 * @return the supplied stream
00839 */
00840 COH_INLINE std::wostream& operator<<(std::wostream& out, const Object& o)
00841     {
00842     String::View vs = o.toString(); // ensure String stays alive while working with the c string
00843     const char* pch = vs->getCString();
00844     if (vs->isCString())  // NUL terminated ASCII
00845         {
00846         out << pch;
00847         }
00848     else if (vs->isASCII()) // ASCII with embedded NULs
00849         {
00850         for (size32_t i = 0, c = vs->length(); i < c; ++i)
00851             {
00852             out << pch[i];
00853             }
00854         }
00855     else // unicode, decode to wchars
00856         {
00857         for (size32_t i = 0, c = vs->length(); i < c; ++i)
00858             {
00859             out << wchar_t(String::next(pch));
00860             }
00861         }
00862     return out;
00863     }
00864 
00865 // ----- helper macros ------------------------------------------------------
00866 
00867 /**
00868 * This macro will take any set of wstreamable contents and turn them into a
00869 * coherence#lang#String instance.
00870 *
00871 * @param CONTENTS  the contents to use in constructing the String.
00872 *
00873 * Usage example:
00874 * @code
00875 * String::Handle hsFoo = COH_TO_WIDE_STRING("This value: " << 5 << " is my value");
00876 * @endcode
00877 */
00878 #define COH_TO_WIDE_STRING(CONTENTS) \
00879     coherence::lang::String::create(((std::wstringstream&) \
00880             (*(COH_AUTO_PTR<std::wstringstream>(new std::wstringstream())) \
00881                 << CONTENTS)).str())
00882 
00883 /**
00884 * This macro will take any set of streamable contents and turn them into a
00885 * coherence#lang#String instance.
00886 *
00887 * @param CONTENTS  the contents to use in constructing the String.
00888 *
00889 * Usage example:
00890 * @code
00891 * String::Handle hsFoo = COH_TO_NARROW_STRING("This value: " << 5 << " is my value");
00892 * @endcode
00893 */
00894 #define COH_TO_NARROW_STRING(CONTENTS) \
00895     coherence::lang::String::create(((std::stringstream&) \
00896             (*(COH_AUTO_PTR<std::stringstream>(new std::stringstream())) \
00897                 << CONTENTS)).str())
00898 
00899 /**
00900  * Compile time option to select the default operator<< to use. If COH_DEFAULT_NARROW_TO_STRING
00901  * is defined then the COH_TO_STRING macro will only require operator<< to be defined
00902  * for std::ostream, alternatively if COH_DEFAULT_WIDE_TO_STRING is then operator<< must be
00903  * defined for std::wostream. The preferable choice is to implement them both via a single template
00904  * based implementation:
00905  *
00906  * template <typename Char, typename Traits> std::basic_ostream<Char, Traits>&
00907  *     operator<<(std::basic_ostream<Char, Traits>& out, const your_class& v)
00908  *
00909  * Note all managed classes deriving from Object (including Managed) are already compatible
00910  * with both stream types, the above operators only need be defined for non-managed
00911  * classes.
00912  */
00913 #if defined(COH_DEFAULT_NARROW_TO_STRING)
00914     #define COH_TO_STRING(CONTENTS) COH_TO_NARROW_STRING(CONTENTS)
00915 #elif defined(COH_DEFAULT_WIDE_TO_STRING)
00916     #define COH_TO_STRING(CONTENTS) COH_TO_WIDE_STRING(CONTENTS)
00917 #elif defined(COH_BUILD) // default coherence internals build to wide
00918     #define COH_TO_STRING(CONTENTS) COH_TO_WIDE_STRING(CONTENTS)
00919 #else // default users to narrow not all types (includeing std::string) are compatible with std::wostream
00920     #define COH_TO_STRING(CONTENTS) COH_TO_NARROW_STRING(CONTENTS)
00921 #endif
00922 
00923 COH_CLOSE_NAMESPACE2
00924 
00925 #endif // COH_STRING_HPP
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.