annotate DEPENDENCIES/generic/include/boost/log/utility/string_literal.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@101 2 * Copyright Andrey Semashev 2007 - 2015.
Chris@16 3 * Distributed under the Boost Software License, Version 1.0.
Chris@16 4 * (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 * http://www.boost.org/LICENSE_1_0.txt)
Chris@16 6 */
Chris@16 7 /*!
Chris@16 8 * \file string_literal.hpp
Chris@16 9 * \author Andrey Semashev
Chris@16 10 * \date 24.06.2007
Chris@16 11 *
Chris@16 12 * The header contains implementation of a constant string literal wrapper.
Chris@16 13 */
Chris@16 14
Chris@16 15 #ifndef BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
Chris@16 16 #define BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_
Chris@16 17
Chris@16 18 #include <cstddef>
Chris@16 19 #include <stdexcept>
Chris@16 20 #include <iosfwd>
Chris@101 21 #include <ios> // std::streamsize
Chris@16 22 #include <string>
Chris@16 23 #include <iterator>
Chris@16 24 #include <boost/operators.hpp>
Chris@16 25 #include <boost/throw_exception.hpp>
Chris@16 26 #include <boost/type_traits/is_same.hpp>
Chris@16 27 #include <boost/utility/enable_if.hpp>
Chris@16 28 #include <boost/log/detail/config.hpp>
Chris@16 29 #include <boost/log/utility/string_literal_fwd.hpp>
Chris@16 30 #include <boost/log/detail/header.hpp>
Chris@16 31
Chris@16 32 #ifdef BOOST_HAS_PRAGMA_ONCE
Chris@16 33 #pragma once
Chris@16 34 #endif
Chris@16 35
Chris@16 36 namespace boost {
Chris@16 37
Chris@16 38 BOOST_LOG_OPEN_NAMESPACE
Chris@16 39
Chris@16 40 /*!
Chris@16 41 * \brief String literal wrapper
Chris@16 42 *
Chris@16 43 * The \c basic_string_literal is a thin wrapper around a constant string literal.
Chris@16 44 * It provides interface similar to STL strings, but because of read-only nature
Chris@16 45 * of string literals, lacks ability to modify string contents. However,
Chris@16 46 * \c basic_string_literal objects can be assigned to and cleared.
Chris@16 47 *
Chris@16 48 * The main advantage of this class comparing to other string classes is that
Chris@16 49 * it doesn't dynamically allocate memory and therefore is fast, thin and exception safe.
Chris@16 50 */
Chris@16 51 template< typename CharT, typename TraitsT >
Chris@16 52 class basic_string_literal
Chris@16 53 //! \cond
Chris@16 54 : public totally_ordered1< basic_string_literal< CharT, TraitsT >,
Chris@16 55 totally_ordered2< basic_string_literal< CharT, TraitsT >, const CharT*,
Chris@16 56 totally_ordered2<
Chris@16 57 basic_string_literal< CharT, TraitsT >,
Chris@16 58 std::basic_string< CharT, TraitsT >
Chris@16 59 >
Chris@16 60 >
Chris@16 61 >
Chris@16 62 //! \endcond
Chris@16 63 {
Chris@16 64 //! Self type
Chris@16 65 typedef basic_string_literal< CharT, TraitsT > this_type;
Chris@16 66
Chris@16 67 public:
Chris@16 68 typedef CharT value_type;
Chris@16 69 typedef TraitsT traits_type;
Chris@16 70
Chris@16 71 typedef std::size_t size_type;
Chris@16 72 typedef std::ptrdiff_t difference_type;
Chris@16 73 typedef const value_type* const_pointer;
Chris@16 74 typedef value_type const& const_reference;
Chris@16 75 typedef const value_type* const_iterator;
Chris@16 76 typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
Chris@16 77
Chris@16 78 //! Corresponding STL string type
Chris@16 79 typedef std::basic_string< value_type, traits_type > string_type;
Chris@16 80
Chris@16 81 private:
Chris@16 82 //! Pointer to the beginning of the literal
Chris@16 83 const_pointer m_pStart;
Chris@16 84 //! Length
Chris@16 85 size_type m_Len;
Chris@16 86
Chris@16 87 //! Empty string literal to support clear
Chris@16 88 static const value_type g_EmptyString[1];
Chris@16 89
Chris@16 90 public:
Chris@16 91 /*!
Chris@16 92 * Constructor
Chris@16 93 *
Chris@16 94 * \post <tt>empty() == true</tt>
Chris@16 95 */
Chris@16 96 basic_string_literal() BOOST_NOEXCEPT { clear(); }
Chris@16 97
Chris@16 98 /*!
Chris@16 99 * Constructor from a string literal
Chris@16 100 *
Chris@16 101 * \post <tt>*this == p</tt>
Chris@16 102 * \param p A zero-terminated constant sequence of characters
Chris@16 103 */
Chris@16 104 template< typename T, size_type LenV >
Chris@16 105 basic_string_literal(T(&p)[LenV]
Chris@16 106 //! \cond
Chris@16 107 , typename enable_if< is_same< T, const value_type >, int >::type = 0
Chris@16 108 //! \endcond
Chris@16 109 ) BOOST_NOEXCEPT
Chris@16 110 : m_pStart(p), m_Len(LenV - 1)
Chris@16 111 {
Chris@16 112 }
Chris@16 113
Chris@16 114 /*!
Chris@16 115 * Copy constructor
Chris@16 116 *
Chris@16 117 * \post <tt>*this == that</tt>
Chris@16 118 * \param that Source literal to copy string from
Chris@16 119 */
Chris@16 120 basic_string_literal(basic_string_literal const& that) BOOST_NOEXCEPT : m_pStart(that.m_pStart), m_Len(that.m_Len) {}
Chris@16 121
Chris@16 122 /*!
Chris@16 123 * Assignment operator
Chris@16 124 *
Chris@16 125 * \post <tt>*this == that</tt>
Chris@16 126 * \param that Source literal to copy string from
Chris@16 127 */
Chris@16 128 this_type& operator= (this_type const& that) BOOST_NOEXCEPT
Chris@16 129 {
Chris@16 130 return assign(that);
Chris@16 131 }
Chris@16 132 /*!
Chris@16 133 * Assignment from a string literal
Chris@16 134 *
Chris@16 135 * \post <tt>*this == p</tt>
Chris@16 136 * \param p A zero-terminated constant sequence of characters
Chris@16 137 */
Chris@16 138 template< typename T, size_type LenV >
Chris@16 139 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 140 typename enable_if<
Chris@16 141 is_same< T, const value_type >,
Chris@16 142 this_type&
Chris@16 143 >::type
Chris@16 144 #else
Chris@16 145 this_type&
Chris@16 146 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 147 operator= (T(&p)[LenV]) BOOST_NOEXCEPT
Chris@16 148 {
Chris@16 149 return assign(p);
Chris@16 150 }
Chris@16 151
Chris@16 152 /*!
Chris@16 153 * Lexicographical comparison (equality)
Chris@16 154 *
Chris@16 155 * \param that Comparand
Chris@16 156 * \return \c true if the comparand string equals to this string, \c false otherwise
Chris@16 157 */
Chris@16 158 bool operator== (this_type const& that) const BOOST_NOEXCEPT
Chris@16 159 {
Chris@16 160 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) == 0);
Chris@16 161 }
Chris@16 162 /*!
Chris@16 163 * Lexicographical comparison (equality)
Chris@16 164 *
Chris@16 165 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
Chris@16 166 * \return \c true if the comparand string equals to this string, \c false otherwise
Chris@16 167 */
Chris@16 168 bool operator== (const_pointer str) const BOOST_NOEXCEPT
Chris@16 169 {
Chris@16 170 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) == 0);
Chris@16 171 }
Chris@16 172 /*!
Chris@16 173 * Lexicographical comparison (equality)
Chris@16 174 *
Chris@16 175 * \param that Comparand
Chris@16 176 * \return \c true if the comparand string equals to this string, \c false otherwise
Chris@16 177 */
Chris@16 178 bool operator== (string_type const& that) const
Chris@16 179 {
Chris@16 180 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) == 0);
Chris@16 181 }
Chris@16 182
Chris@16 183 /*!
Chris@16 184 * Lexicographical comparison (less ordering)
Chris@16 185 *
Chris@16 186 * \param that Comparand
Chris@16 187 * \return \c true if this string is less than the comparand, \c false otherwise
Chris@16 188 */
Chris@16 189 bool operator< (this_type const& that) const BOOST_NOEXCEPT
Chris@16 190 {
Chris@16 191 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) < 0);
Chris@16 192 }
Chris@16 193 /*!
Chris@16 194 * Lexicographical comparison (less ordering)
Chris@16 195 *
Chris@16 196 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
Chris@16 197 * \return \c true if this string is less than the comparand, \c false otherwise
Chris@16 198 */
Chris@16 199 bool operator< (const_pointer str) const BOOST_NOEXCEPT
Chris@16 200 {
Chris@16 201 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) < 0);
Chris@16 202 }
Chris@16 203 /*!
Chris@16 204 * Lexicographical comparison (less ordering)
Chris@16 205 *
Chris@16 206 * \param that Comparand
Chris@16 207 * \return \c true if this string is less than the comparand, \c false otherwise
Chris@16 208 */
Chris@16 209 bool operator< (string_type const& that) const
Chris@16 210 {
Chris@16 211 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) < 0);
Chris@16 212 }
Chris@16 213
Chris@16 214 /*!
Chris@16 215 * Lexicographical comparison (greater ordering)
Chris@16 216 *
Chris@16 217 * \param that Comparand
Chris@16 218 * \return \c true if this string is greater than the comparand, \c false otherwise
Chris@16 219 */
Chris@16 220 bool operator> (this_type const& that) const BOOST_NOEXCEPT
Chris@16 221 {
Chris@16 222 return (compare_internal(m_pStart, m_Len, that.m_pStart, that.m_Len) > 0);
Chris@16 223 }
Chris@16 224 /*!
Chris@16 225 * Lexicographical comparison (greater ordering)
Chris@16 226 *
Chris@16 227 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
Chris@16 228 * \return \c true if this string is greater than the comparand, \c false otherwise
Chris@16 229 */
Chris@16 230 bool operator> (const_pointer str) const BOOST_NOEXCEPT
Chris@16 231 {
Chris@16 232 return (compare_internal(m_pStart, m_Len, str, traits_type::length(str)) > 0);
Chris@16 233 }
Chris@16 234 /*!
Chris@16 235 * Lexicographical comparison (greater ordering)
Chris@16 236 *
Chris@16 237 * \param that Comparand
Chris@16 238 * \return \c true if this string is greater than the comparand, \c false otherwise
Chris@16 239 */
Chris@16 240 bool operator> (string_type const& that) const
Chris@16 241 {
Chris@16 242 return (compare_internal(m_pStart, m_Len, that.c_str(), that.size()) > 0);
Chris@16 243 }
Chris@16 244
Chris@16 245 /*!
Chris@16 246 * Subscript operator
Chris@16 247 *
Chris@16 248 * \pre <tt>i < size()</tt>
Chris@16 249 * \param i Requested character index
Chris@16 250 * \return Constant reference to the requested character
Chris@16 251 */
Chris@16 252 const_reference operator[] (size_type i) const BOOST_NOEXCEPT
Chris@16 253 {
Chris@16 254 return m_pStart[i];
Chris@16 255 }
Chris@16 256 /*!
Chris@16 257 * Checked subscript
Chris@16 258 *
Chris@16 259 * \param i Requested character index
Chris@16 260 * \return Constant reference to the requested character
Chris@16 261 *
Chris@16 262 * \b Throws: An <tt>std::exception</tt>-based exception if index \a i is out of string boundaries
Chris@16 263 */
Chris@16 264 const_reference at(size_type i) const
Chris@16 265 {
Chris@16 266 if (i >= m_Len)
Chris@16 267 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::at: the index value is out of range"));
Chris@16 268 return m_pStart[i];
Chris@16 269 }
Chris@16 270
Chris@16 271 /*!
Chris@16 272 * \return Pointer to the beginning of the literal
Chris@16 273 */
Chris@16 274 const_pointer c_str() const BOOST_NOEXCEPT { return m_pStart; }
Chris@16 275 /*!
Chris@16 276 * \return Pointer to the beginning of the literal
Chris@16 277 */
Chris@16 278 const_pointer data() const BOOST_NOEXCEPT { return m_pStart; }
Chris@16 279 /*!
Chris@16 280 * \return Length of the literal
Chris@16 281 */
Chris@16 282 size_type size() const BOOST_NOEXCEPT { return m_Len; }
Chris@16 283 /*!
Chris@16 284 * \return Length of the literal
Chris@16 285 */
Chris@16 286 size_type length() const BOOST_NOEXCEPT { return m_Len; }
Chris@16 287
Chris@16 288 /*!
Chris@16 289 * \return \c true if the literal is an empty string, \c false otherwise
Chris@16 290 */
Chris@16 291 bool empty() const BOOST_NOEXCEPT
Chris@16 292 {
Chris@16 293 return (m_Len == 0);
Chris@16 294 }
Chris@16 295
Chris@16 296 /*!
Chris@16 297 * \return Iterator that points to the first character of the literal
Chris@16 298 */
Chris@16 299 const_iterator begin() const BOOST_NOEXCEPT { return m_pStart; }
Chris@16 300 /*!
Chris@16 301 * \return Iterator that points after the last character of the literal
Chris@16 302 */
Chris@16 303 const_iterator end() const BOOST_NOEXCEPT { return m_pStart + m_Len; }
Chris@16 304 /*!
Chris@16 305 * \return Reverse iterator that points to the last character of the literal
Chris@16 306 */
Chris@16 307 const_reverse_iterator rbegin() const BOOST_NOEXCEPT { return const_reverse_iterator(end()); }
Chris@16 308 /*!
Chris@16 309 * \return Reverse iterator that points before the first character of the literal
Chris@16 310 */
Chris@16 311 const_reverse_iterator rend() const BOOST_NOEXCEPT { return const_reverse_iterator(begin()); }
Chris@16 312
Chris@16 313 /*!
Chris@16 314 * \return STL string constructed from the literal
Chris@16 315 */
Chris@16 316 string_type str() const
Chris@16 317 {
Chris@16 318 return string_type(m_pStart, m_Len);
Chris@16 319 }
Chris@16 320
Chris@16 321 /*!
Chris@16 322 * The method clears the literal
Chris@16 323 *
Chris@16 324 * \post <tt>empty() == true</tt>
Chris@16 325 */
Chris@16 326 void clear() BOOST_NOEXCEPT
Chris@16 327 {
Chris@16 328 m_pStart = g_EmptyString;
Chris@16 329 m_Len = 0;
Chris@16 330 }
Chris@16 331 /*!
Chris@16 332 * The method swaps two literals
Chris@16 333 */
Chris@16 334 void swap(this_type& that) BOOST_NOEXCEPT
Chris@16 335 {
Chris@101 336 const_pointer p = m_pStart;
Chris@16 337 m_pStart = that.m_pStart;
Chris@16 338 that.m_pStart = p;
Chris@16 339
Chris@101 340 size_type l = m_Len;
Chris@16 341 m_Len = that.m_Len;
Chris@16 342 that.m_Len = l;
Chris@16 343 }
Chris@16 344
Chris@16 345 /*!
Chris@16 346 * Assignment from another literal
Chris@16 347 *
Chris@16 348 * \post <tt>*this == that</tt>
Chris@16 349 * \param that Source literal to copy string from
Chris@16 350 */
Chris@16 351 this_type& assign(this_type const& that) BOOST_NOEXCEPT
Chris@16 352 {
Chris@16 353 m_pStart = that.m_pStart;
Chris@16 354 m_Len = that.m_Len;
Chris@16 355 return *this;
Chris@16 356 }
Chris@16 357 /*!
Chris@16 358 * Assignment from another literal
Chris@16 359 *
Chris@16 360 * \post <tt>*this == p</tt>
Chris@16 361 * \param p A zero-terminated constant sequence of characters
Chris@16 362 */
Chris@16 363 template< typename T, size_type LenV >
Chris@16 364 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 365 typename enable_if<
Chris@16 366 is_same< T, const value_type >,
Chris@16 367 this_type&
Chris@16 368 >::type
Chris@16 369 #else
Chris@16 370 this_type&
Chris@16 371 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 372 assign(T(&p)[LenV]) BOOST_NOEXCEPT
Chris@16 373 {
Chris@16 374 m_pStart = p;
Chris@16 375 m_Len = LenV - 1;
Chris@16 376 return *this;
Chris@16 377 }
Chris@16 378
Chris@16 379 /*!
Chris@16 380 * The method copies the literal or its portion to an external buffer
Chris@16 381 *
Chris@16 382 * \pre <tt>pos <= size()</tt>
Chris@16 383 * \param str Pointer to the external buffer beginning. Must not be NULL.
Chris@16 384 * The buffer must have enough capacity to accommodate the requested number of characters.
Chris@16 385 * \param n Maximum number of characters to copy
Chris@16 386 * \param pos Starting position to start copying from
Chris@16 387 * \return Number of characters copied
Chris@16 388 *
Chris@16 389 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
Chris@16 390 */
Chris@16 391 size_type copy(value_type* str, size_type n, size_type pos = 0) const
Chris@16 392 {
Chris@16 393 if (pos > m_Len)
Chris@16 394 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::copy: the position is out of range"));
Chris@16 395
Chris@101 396 size_type len = m_Len - pos;
Chris@16 397 if (len > n)
Chris@16 398 len = n;
Chris@16 399 traits_type::copy(str, m_pStart + pos, len);
Chris@16 400 return len;
Chris@16 401 }
Chris@16 402
Chris@16 403 /*!
Chris@16 404 * Lexicographically compares the argument string to a part of this string
Chris@16 405 *
Chris@16 406 * \pre <tt>pos <= size()</tt>
Chris@16 407 * \param pos Starting position within this string to perform comparison to
Chris@16 408 * \param n Length of the substring of this string to perform comparison to
Chris@16 409 * \param str Comparand. Must point to a sequence of characters, must not be NULL.
Chris@16 410 * \param len Number of characters in the sequence \a str.
Chris@16 411 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 412 * a positive value if this string is greater than the comparand.
Chris@16 413 *
Chris@16 414 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
Chris@16 415 */
Chris@16 416 int compare(size_type pos, size_type n, const_pointer str, size_type len) const
Chris@16 417 {
Chris@16 418 if (pos > m_Len)
Chris@16 419 BOOST_THROW_EXCEPTION(std::out_of_range("basic_string_literal::compare: the position is out of range"));
Chris@16 420
Chris@101 421 size_type compare_size = m_Len - pos;
Chris@16 422 if (compare_size > len)
Chris@16 423 compare_size = len;
Chris@16 424 if (compare_size > n)
Chris@16 425 compare_size = n;
Chris@16 426 return compare_internal(m_pStart + pos, compare_size, str, compare_size);
Chris@16 427 }
Chris@16 428 /*!
Chris@16 429 * Lexicographically compares the argument string to a part of this string
Chris@16 430 *
Chris@16 431 * \pre <tt>pos <= size()</tt>
Chris@16 432 * \param pos Starting position within this string to perform comparison to
Chris@16 433 * \param n Length of the substring of this string to perform comparison to
Chris@16 434 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
Chris@16 435 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 436 * a positive value if this string is greater than the comparand.
Chris@16 437 *
Chris@16 438 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
Chris@16 439 */
Chris@16 440 int compare(size_type pos, size_type n, const_pointer str) const BOOST_NOEXCEPT
Chris@16 441 {
Chris@16 442 return compare(pos, n, str, traits_type::length(str));
Chris@16 443 }
Chris@16 444 /*!
Chris@16 445 * Lexicographically compares the argument string literal to a part of this string
Chris@16 446 *
Chris@16 447 * \pre <tt>pos <= size()</tt>
Chris@16 448 * \param pos Starting position within this string to perform comparison to
Chris@16 449 * \param n Length of the substring of this string to perform comparison to
Chris@16 450 * \param that Comparand
Chris@16 451 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 452 * a positive value if this string is greater than the comparand.
Chris@16 453 *
Chris@16 454 * \b Throws: An <tt>std::exception</tt>-based exception if \a pos is out of range.
Chris@16 455 */
Chris@16 456 int compare(size_type pos, size_type n, this_type const& that) const BOOST_NOEXCEPT
Chris@16 457 {
Chris@16 458 return compare(pos, n, that.c_str(), that.size());
Chris@16 459 }
Chris@16 460 /*!
Chris@16 461 * Lexicographically compares the argument string to this string
Chris@16 462 *
Chris@16 463 * \param str Comparand. Must point to a sequence of characters, must not be NULL.
Chris@16 464 * \param len Number of characters in the sequence \a str.
Chris@16 465 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 466 * a positive value if this string is greater than the comparand.
Chris@16 467 */
Chris@16 468 int compare(const_pointer str, size_type len) const BOOST_NOEXCEPT
Chris@16 469 {
Chris@16 470 return compare(0, m_Len, str, len);
Chris@16 471 }
Chris@16 472 /*!
Chris@16 473 * Lexicographically compares the argument string to this string
Chris@16 474 *
Chris@16 475 * \param str Comparand. Must point to a zero-terminated sequence of characters, must not be NULL.
Chris@16 476 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 477 * a positive value if this string is greater than the comparand.
Chris@16 478 */
Chris@16 479 int compare(const_pointer str) const BOOST_NOEXCEPT
Chris@16 480 {
Chris@16 481 return compare(0, m_Len, str, traits_type::length(str));
Chris@16 482 }
Chris@16 483 /*!
Chris@16 484 * Lexicographically compares the argument string to this string
Chris@16 485 *
Chris@16 486 * \param that Comparand
Chris@16 487 * \return Zero if the comparand equals this string, a negative value if this string is less than the comparand,
Chris@16 488 * a positive value if this string is greater than the comparand.
Chris@16 489 */
Chris@16 490 int compare(this_type const& that) const BOOST_NOEXCEPT
Chris@16 491 {
Chris@16 492 return compare(0, m_Len, that.c_str(), that.size());
Chris@16 493 }
Chris@16 494
Chris@16 495 private:
Chris@16 496 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 497 //! Internal comparison implementation
Chris@16 498 static int compare_internal(const_pointer pLeft, size_type LeftLen, const_pointer pRight, size_type RightLen) BOOST_NOEXCEPT
Chris@16 499 {
Chris@16 500 if (pLeft != pRight)
Chris@16 501 {
Chris@101 502 const int result = traits_type::compare(pLeft, pRight, (LeftLen < RightLen ? LeftLen : RightLen));
Chris@16 503 if (result != 0)
Chris@16 504 return result;
Chris@16 505 }
Chris@16 506 return LeftLen < RightLen ? -1 : (LeftLen > RightLen ? 1 : 0);
Chris@16 507 }
Chris@16 508 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 509 };
Chris@16 510
Chris@16 511 template< typename CharT, typename TraitsT >
Chris@16 512 typename basic_string_literal< CharT, TraitsT >::value_type const
Chris@16 513 basic_string_literal< CharT, TraitsT >::g_EmptyString[1] = { 0 };
Chris@16 514
Chris@16 515 namespace aux {
Chris@16 516
Chris@16 517 template< typename CharT, typename TraitsT >
Chris@16 518 inline void insert_fill_chars(std::basic_ostream< CharT, TraitsT >& strm, std::size_t n)
Chris@16 519 {
Chris@16 520 enum { chunk_size = 8 };
Chris@16 521 CharT fill_chars[chunk_size];
Chris@16 522 const CharT filler = strm.fill();
Chris@16 523 for (unsigned int i = 0; i < chunk_size; ++i)
Chris@16 524 fill_chars[i] = filler;
Chris@16 525 for (; n >= chunk_size && strm.good(); n -= chunk_size)
Chris@16 526 strm.write(fill_chars, static_cast< std::size_t >(chunk_size));
Chris@16 527 if (n > 0 && strm.good())
Chris@16 528 strm.write(fill_chars, n);
Chris@16 529 }
Chris@16 530
Chris@16 531 template< typename CharT, typename TraitsT >
Chris@16 532 void insert_aligned(std::basic_ostream< CharT, TraitsT >& strm, const CharT* p, std::size_t size)
Chris@16 533 {
Chris@16 534 const std::size_t alignment_size = static_cast< std::size_t >(strm.width()) - size;
Chris@16 535 const bool align_left = (strm.flags() & std::basic_ostream< CharT, TraitsT >::adjustfield) == std::basic_ostream< CharT, TraitsT >::left;
Chris@16 536 if (align_left)
Chris@16 537 {
Chris@16 538 strm.write(p, size);
Chris@16 539 if (strm.good())
Chris@16 540 aux::insert_fill_chars(strm, alignment_size);
Chris@16 541 }
Chris@16 542 else
Chris@16 543 {
Chris@16 544 aux::insert_fill_chars(strm, alignment_size);
Chris@16 545 if (strm.good())
Chris@16 546 strm.write(p, size);
Chris@16 547 }
Chris@16 548 }
Chris@16 549
Chris@16 550 } // namespace aux
Chris@16 551
Chris@16 552 //! Output operator
Chris@16 553 template< typename CharT, typename StrmTraitsT, typename LitTraitsT >
Chris@16 554 inline std::basic_ostream< CharT, StrmTraitsT >& operator<< (
Chris@16 555 std::basic_ostream< CharT, StrmTraitsT >& strm, basic_string_literal< CharT, LitTraitsT > const& lit)
Chris@16 556 {
Chris@16 557 if (strm.good())
Chris@16 558 {
Chris@16 559 const std::size_t size = lit.size();
Chris@16 560 const std::size_t w = static_cast< std::size_t >(strm.width());
Chris@16 561 if (w <= size)
Chris@16 562 strm.write(lit.c_str(), static_cast< std::streamsize >(size));
Chris@16 563 else
Chris@16 564 aux::insert_aligned(strm, lit.c_str(), lit.size());
Chris@16 565 strm.width(0);
Chris@16 566 }
Chris@16 567 return strm;
Chris@16 568 }
Chris@16 569
Chris@16 570 //! External swap
Chris@16 571 template< typename CharT, typename TraitsT >
Chris@16 572 inline void swap(basic_string_literal< CharT, TraitsT >& left, basic_string_literal< CharT, TraitsT >& right) BOOST_NOEXCEPT
Chris@16 573 {
Chris@16 574 left.swap(right);
Chris@16 575 }
Chris@16 576
Chris@16 577 //! Creates a string literal wrapper from a constant string literal
Chris@16 578 #ifdef BOOST_LOG_USE_CHAR
Chris@16 579 template< typename T, std::size_t LenV >
Chris@16 580 inline
Chris@16 581 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 582 typename enable_if<
Chris@16 583 is_same< T, const char >,
Chris@16 584 string_literal
Chris@16 585 >::type
Chris@16 586 #else
Chris@16 587 basic_string_literal< T >
Chris@16 588 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 589 str_literal(T(&p)[LenV])
Chris@16 590 {
Chris@16 591 return string_literal(p);
Chris@16 592 }
Chris@16 593 #endif
Chris@16 594
Chris@16 595 #ifndef BOOST_LOG_DOXYGEN_PASS
Chris@16 596
Chris@16 597 #ifdef BOOST_LOG_USE_WCHAR_T
Chris@16 598 template< typename T, std::size_t LenV >
Chris@16 599 inline typename enable_if<
Chris@16 600 is_same< T, const wchar_t >,
Chris@16 601 wstring_literal
Chris@16 602 >::type
Chris@16 603 str_literal(T(&p)[LenV])
Chris@16 604 {
Chris@16 605 return wstring_literal(p);
Chris@16 606 }
Chris@16 607 #endif
Chris@16 608
Chris@16 609 #endif // BOOST_LOG_DOXYGEN_PASS
Chris@16 610
Chris@16 611 BOOST_LOG_CLOSE_NAMESPACE // namespace log
Chris@16 612
Chris@16 613 } // namespace boost
Chris@16 614
Chris@16 615 #include <boost/log/detail/footer.hpp>
Chris@16 616
Chris@16 617 #endif // BOOST_LOG_UTILITY_STRING_LITERAL_HPP_INCLUDED_