/* * Copyright (c) 2017 Jaroslav Jindrak * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LIBCPP_INTERNAL_STRING #define LIBCPP_INTERNAL_STRING #include #include namespace std { /** * 21.4.8.9, inserters and extractors: */ template basic_istream& operator>>(basic_istream& is, basic_string& str) { using sentry = typename basic_istream::sentry; sentry sen{is, false}; if (sen) { str.erase(); auto max_size = is.width(); if (max_size <= 0) max_size = static_cast(str.max_size()); streamsize i{}; for(; i < max_size; ++i) { auto ic = is.rdbuf()->sgetc(); if (Traits::eq_int_type(ic, Traits::eof())) { is.setstate(ios_base::eofbit); break; } auto c = Traits::to_char_type(ic); if(isspace(c, is.getloc())) break; str.push_back(c); is.rdbuf()->sbumpc(); } if (i == 0) is.setstate(ios_base::failbit); } else is.setstate(ios_base::failbit); return is; } template basic_ostream& operator<<(basic_ostream& os, basic_string& str) { // TODO: determine padding as described in 27.7.3.6.1 using sentry = typename basic_ostream::sentry; sentry sen{os}; if (sen) { auto width = os.width(); auto size = str.size(); size_t to_pad{}; if (width > 0) to_pad = (static_cast(width) - size); if (to_pad > 0) { if ((os.flags() & ios_base::adjustfield) != ios_base::left) { for (std::size_t i = 0; i < to_pad; ++i) os.put(os.fill()); } os.rdbuf()->sputn(str.data(), size); if ((os.flags() & ios_base::adjustfield) == ios_base::left) { for (std::size_t i = 0; i < to_pad; ++i) os.put(os.fill()); } } else os.rdbuf()->sputn(str.data(), size); os.width(0); } return os; } template basic_istream& getline(basic_istream& is, basic_string& str, Char delim) { typename basic_istream::sentry sen{is, true}; if (sen) { str.clear(); streamsize count{}; while (true) { auto ic = is.rdbuf()->sbumpc(); if (Traits::eq_int_type(ic, Traits::eof())) { is.setstate(ios_base::eofbit); break; } auto c = Traits::to_char_type(ic); if (Traits::eq(c, delim)) break; str.push_back(c); ++count; if (count >= static_cast(str.max_size())) { is.setstate(ios_base::failbit); break; } } if (count == 0) is.setstate(ios_base::failbit); } else is.setstate(ios_base::failbit); return is; } template basic_istream& getline(basic_istream&& is, basic_string& str, Char delim) { return getline(is, str, delim); } template basic_istream& getline(basic_istream& is, basic_string& str) { return getline(is, str, is.widen('\n')); } template basic_istream& getline(basic_istream&& is, basic_string& str) { return getline(is, str, is.widen('\n')); } } #endif