mirror of git://gcc.gnu.org/git/gcc.git
[multiple changes]
2002-02-04 Phil Edwards <pme@gcc.gnu.org> * docs/doxygen/TODO: Impl-defined behavior now documented... * docs/html/17_intro/howto.html: ...here. * docs/doxygen/mainpage.doxy: Remove, rename... * docs/doxygen/mainpage.html: ...to this. Tweak HTML, add license. * docs/doxygen/style.css: Add small text. * docs/doxygen/run_doxygen: Adjust for new mainpage. * docs/doxygen/user.cfg.in: Likewise. 2002-02-04 Stephan Buys <s.buys@icon.co.za> * include/bits/stl_map.h: Initial doxygen markup. * include/std/std_fstream.h: Initial doxygen markup. From-SVN: r49502
This commit is contained in:
parent
ebbb0a63f4
commit
fd58f127a6
|
|
@ -1,3 +1,18 @@
|
|||
2002-02-04 Phil Edwards <pme@gcc.gnu.org>
|
||||
|
||||
* docs/doxygen/TODO: Impl-defined behavior now documented...
|
||||
* docs/html/17_intro/howto.html: ...here.
|
||||
* docs/doxygen/mainpage.doxy: Remove, rename...
|
||||
* docs/doxygen/mainpage.html: ...to this. Tweak HTML, add license.
|
||||
* docs/doxygen/style.css: Add small text.
|
||||
* docs/doxygen/run_doxygen: Adjust for new mainpage.
|
||||
* docs/doxygen/user.cfg.in: Likewise.
|
||||
|
||||
2002-02-04 Stephan Buys <s.buys@icon.co.za>
|
||||
|
||||
* include/bits/stl_map.h: Initial doxygen markup.
|
||||
* include/std/std_fstream.h: Initial doxygen markup.
|
||||
|
||||
2002-02-04 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
libstdc++/5579
|
||||
|
|
|
|||
|
|
@ -30,13 +30,6 @@ ext/* Some of the SGI algorithm/functional extensions.
|
|||
|
||||
__gnu_cxx Tricky. Right now ext/* are in this namespace.
|
||||
|
||||
[1.3.5] "implementation-defined behavior: behavior ... that depends
|
||||
on the implementation *and that each implementation shall
|
||||
document*." [my emphasis] Not all implementation choices
|
||||
have been thus described; doxygen is not necessarily the
|
||||
appropriate place for such descriptions, either. I suggest
|
||||
adding this list to the Chapter 17 HOWTO.
|
||||
|
||||
-----------------------------------------------------------
|
||||
|
||||
NOTES:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,32 @@
|
|||
/*! \mainpage
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Main Page</title>
|
||||
<link href="style.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
|
||||
<body bgcolor="#ffffff">
|
||||
<!--
|
||||
Originally generated by Doxygen 1.2.12.
|
||||
|
||||
This used to be surrounded by /* */ marks and tagged with @mainpage, so
|
||||
that Doxygen would create the index page from it. HOWEVER, Doxygen
|
||||
ignores all but the most basic HTML tags, and even with those it strips
|
||||
all the attributes. (See, the HTML you write for @mainpage isn't used
|
||||
directly; it all gets run through Doxygen and re-output.) So lots of
|
||||
tags were all being mangled.
|
||||
|
||||
Funk 'dat. Now we let Doxygen do whateer it feels like doing for the
|
||||
index page, and then we just flat copy this over top of it. Voila!
|
||||
Tags actually work like they're supposed to.
|
||||
-->
|
||||
|
||||
<h1>libstdc++-v3 Source Documentation</h1>
|
||||
|
||||
<h2> Documentation Overview </h2>
|
||||
|
||||
<p class="smallertext">Generated 2002-02-04.</p>
|
||||
|
||||
<p>There are two types of documentation for libstdc++-v3. One is the
|
||||
distribution documentation, which can be read online at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/documentation.html">http://gcc.gnu.org/onlinedocs/libstdc++/documentation.html</a>
|
||||
|
|
@ -26,8 +51,12 @@
|
|||
The Makefile rule <code> 'make
|
||||
doxygen' </code> in the libstdc++-v3 build directory generates these pages
|
||||
using a tool called, appropriately enough, Doxygen. To learn more about
|
||||
Doxygen, take a look at <a href="http://www.doxygen.org">the Doxygen
|
||||
webpage</a>.
|
||||
Doxygen, take a look at
|
||||
<a href="http://www.doxygen.org/">
|
||||
<!-- snagged from the generated page -->
|
||||
<img src="doxygen.gif" alt="the Doxygen homepage"
|
||||
align=center border=0 width=110 height=53>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>The libstdc++-v3 configuration files needed to generate doxygen output
|
||||
|
|
@ -71,6 +100,31 @@ href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/C++STYLE">C++STYLE</a>.
|
|||
</ul>
|
||||
</p>
|
||||
|
||||
*/
|
||||
|
||||
<h2> License, Copyright, and Other Lawyerly Verbosity </h2>
|
||||
<p>The libstdc++-v3 documentation is released under
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/license.html">
|
||||
these terms</a>.
|
||||
</p>
|
||||
<p>Part of the generated documentation involved comments
|
||||
and notes from SGI, who says we gotta say this:
|
||||
<blockquote>
|
||||
Permission to use, copy, modify, distribute and sell this software and its
|
||||
documentation for any purpose is hereby granted without fee, provided
|
||||
that the below copyright notice appears in all copies and that both
|
||||
the copyright notice and this permission notice appear in supporting
|
||||
documentation. Silicon Graphics makes no representations about the
|
||||
suitability of this software for any purpose. It is provided "as is"
|
||||
without express or implied warranty.
|
||||
<br><br>
|
||||
Copyright © 1994
|
||||
Hewlett-Packard Company
|
||||
</blockquote>
|
||||
</p>
|
||||
<p>Part of the generated documentation is quoted from the C++ standard, which
|
||||
is copyright 1998 by Information Technology Industry Council.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -146,6 +146,7 @@ set -e
|
|||
set +e
|
||||
|
||||
test $do_html = yes && {
|
||||
cp ${srcdir}/docs/doxygen/mainpage.html ${outdir}/html_${mode}/index.html
|
||||
echo ::
|
||||
echo :: HTML pages begin with
|
||||
echo :: ${outdir}/html_${mode}/index.html
|
||||
|
|
|
|||
|
|
@ -21,3 +21,4 @@ FONT.comment { color: #800000 }
|
|||
FONT.preprocessor { color: #806020 }
|
||||
FONT.stringliteral { color: #002080 }
|
||||
FONT.charliteral { color: #008080 }
|
||||
.smallertext { font-size: smaller }
|
||||
|
|
|
|||
|
|
@ -296,8 +296,7 @@ WARN_LOGFILE =
|
|||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = @srcdir@/docs/doxygen/mainpage.doxy \
|
||||
@srcdir@/docs/doxygen/doxygroups.cc \
|
||||
INPUT = @srcdir@/docs/doxygen/doxygroups.cc \
|
||||
@srcdir@/src \
|
||||
@srcdir@/libsupc++/exception \
|
||||
@srcdir@/libsupc++/new \
|
||||
|
|
|
|||
|
|
@ -165,26 +165,28 @@
|
|||
|
||||
<hr>
|
||||
<h2><a name="5">Behavior specific to libstdc++-v3</a></h2>
|
||||
<p>The ISO standard defines the following:
|
||||
<p>The ISO standard defines the following phrase:
|
||||
<blockquote><dl>
|
||||
<dt><code>[1.3.5] implementation-defined behavior</code>
|
||||
<dd>behavior, for a well-formed program construct and correct data, that
|
||||
depends on the implementation <strong>and that each implementation
|
||||
shall document</strong>.
|
||||
shall document</strong>.
|
||||
</dl></blockquote>
|
||||
We do so here, for the C++ library only. Behavior of the compiler,
|
||||
linker, runtime loader, and other elements of "the
|
||||
implementation" are documented elsewhere.
|
||||
implementation" are documented elsewhere. Everything listed in
|
||||
Annex B, Implemenation Qualities, are also part of the compiler, not
|
||||
the library.
|
||||
</p>
|
||||
<p>For each entry, we give the section number of the standard, when
|
||||
applicable. This list is known to be incomplet and inkorrekt.
|
||||
applicable. This list is probably incomplet and inkorrekt.
|
||||
</p>
|
||||
<p><strong>[17.4.4.5]</strong> Non-reentrant functions are probably best
|
||||
discussed in the various sections on multithreading (see above).
|
||||
</p>
|
||||
<!-- [17.4.4.8]/3 says any function that doesn't have an exception-spec
|
||||
can throw whatever we want; see also its footnote. Let's list those
|
||||
in the sections where the function itself occurs.
|
||||
in the sections where the function itself occurs.
|
||||
-->
|
||||
<p><strong>[18.1]/4</strong> The type of <code>NULL</code> is described
|
||||
<a href="../18_support/howto.html#1">here</a>.
|
||||
|
|
@ -200,27 +202,66 @@
|
|||
<strong>[18.6.2.1]/5</strong> (bad_exception): The <code>what()</code>
|
||||
member function of class <code>std::exception</code>, and these other
|
||||
classes publicly derived from it, simply returns the name of the
|
||||
class. But they are the <em>mangled</em> names.
|
||||
<!-- demangler bug fixed yet? -->
|
||||
class. But they are the <em>mangled</em> names; you will need to call
|
||||
<code>c++filt</code> and pass the names as command-line parameters to
|
||||
demangle them.
|
||||
(The classes in <code><stdexcept></code> have constructors which
|
||||
require a string argument to use in <code>what()</code> calls, so the
|
||||
require an argument to use later for <code>what()</code> calls, so the
|
||||
question does not arise in most user-defined exceptions.)
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[18.5.1]/7</strong> The return value of
|
||||
<code>std::type_info::name()</code> is the mangled type name (see the
|
||||
previous entry for more).
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[20.1.5]/5</strong> <em>"Implementors are encouraged to
|
||||
supply libraries that can accept allocators that encapsulate more
|
||||
general memory models and that support non-equal instances. In such
|
||||
implementations, any requirements imposed on allocators by containers
|
||||
beyond those requirements that appear in Table 32, and the semantics
|
||||
of containers and algorithms when allocator instances compare
|
||||
non-equal, are implementation-defined."</em> As yet we don't
|
||||
have any allocators which compare non-equal, so we can't describe how
|
||||
they behave.
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[21.1.3.1]/3,4</strong>,<br>
|
||||
<strong>[21.1.3.2]/2</strong>,<br>
|
||||
<strong>[23.*]'s foo::iterator</strong>,<br>
|
||||
<strong>[27.*]'s foo::*_type</strong>,<br>
|
||||
<strong>others...</strong>
|
||||
Nope, these types are called implementation-defined because you
|
||||
shouldn't be taking advantage of their underlying types. Listing them
|
||||
here would defeat the purpose. :-)
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[21.1.3.1]/5</strong> I don't really know about the mbstate_t
|
||||
stuff... see the chapter 22 notes for what does exist.
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[22.*]</strong> Anything and everything we have on locale
|
||||
implemenation will be described
|
||||
<a href="../22_locale/howto.html">over here</a>.
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[26.2.8]/9</strong> I have no idea what
|
||||
<code>complex<T></code>'s pow(0,0) returns.
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>[27.4.2.4]/2</strong> Calling
|
||||
<code>std::ios_base::sync_with_stdio</code> after I/O has already been
|
||||
performed on the standard stream objects will
|
||||
flush the buffers, and <!-- this line might go away -->
|
||||
destroy and recreate the underlying buffer instances. Whether or not
|
||||
the previously-written I/O is destroyed in this process depends mostly
|
||||
on the --enable-libio choice: for stdio, if the written data is
|
||||
already in the stdio buffer, the data may be completely safe!
|
||||
</p>
|
||||
<p><strong></strong>
|
||||
<p><strong>I/O sentry ctor/dtor</strong> They can perform additional work
|
||||
than the minimum required. I don't think we're currently taking
|
||||
advantage of this yet.
|
||||
</p>
|
||||
<p><strong>[27.7.1.3]/16</strong>,<br>
|
||||
<strong>[27.8.1.4]/10</strong>
|
||||
The effects of <code>pubsetbuf/setbuf</code> are described
|
||||
<a href="../27_io/howto.html#2">in this chapter</a>.
|
||||
</p>
|
||||
<p><strong>[27.8.1.4]/16</strong> Calling <code>fstream::sync</code> when
|
||||
a get area exists will... whatever <code>fflush()</code> does, I think.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// Map implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
|
|
@ -66,6 +66,14 @@
|
|||
namespace std
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief A standard container made up of pairs (see std::pair in <utility>)
|
||||
* which can be retrieved based on a key.
|
||||
*
|
||||
* This is an associative container. Values contained within it can be
|
||||
* quickly retrieved through a key element. Example: MyMap["First"] would
|
||||
* return the data associated with the key "First".
|
||||
*/
|
||||
template <class _Key, class _Tp, class _Compare = less<_Key>,
|
||||
class _Alloc = allocator<pair<const _Key, _Tp> > >
|
||||
class map
|
||||
|
|
@ -81,7 +89,7 @@ public:
|
|||
typedef _Tp mapped_type;
|
||||
typedef pair<const _Key, _Tp> value_type;
|
||||
typedef _Compare key_compare;
|
||||
|
||||
|
||||
class value_compare
|
||||
: public binary_function<value_type, value_type, bool> {
|
||||
friend class map<_Key,_Tp,_Compare,_Alloc>;
|
||||
|
|
@ -95,7 +103,7 @@ public:
|
|||
};
|
||||
|
||||
private:
|
||||
typedef _Rb_tree<key_type, value_type,
|
||||
typedef _Rb_tree<key_type, value_type,
|
||||
_Select1st<value_type>, key_compare, _Alloc> _Rep_type;
|
||||
_Rep_type _M_t; // red-black tree representing map
|
||||
public:
|
||||
|
|
@ -133,7 +141,7 @@ public:
|
|||
operator=(const map<_Key, _Tp, _Compare, _Alloc>& __x)
|
||||
{
|
||||
_M_t = __x._M_t;
|
||||
return *this;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// accessors:
|
||||
|
|
@ -142,17 +150,73 @@ public:
|
|||
value_compare value_comp() const { return value_compare(_M_t.key_comp()); }
|
||||
allocator_type get_allocator() const { return _M_t.get_allocator(); }
|
||||
|
||||
/**
|
||||
* Returns a read/write iterator that points to the first pair in the map.
|
||||
* Iteration is done in ascending order according to the keys.
|
||||
*/
|
||||
iterator begin() { return _M_t.begin(); }
|
||||
|
||||
/**
|
||||
* Returns a read-only (constant) iterator that points to the first pair
|
||||
* in the map. Iteration is done in ascending order according to the keys.
|
||||
*/
|
||||
const_iterator begin() const { return _M_t.begin(); }
|
||||
|
||||
/**
|
||||
* Returns a read/write iterator that points one past the last pair in the
|
||||
* map. Iteration is done in ascending order according to the keys.
|
||||
*/
|
||||
iterator end() { return _M_t.end(); }
|
||||
|
||||
/**
|
||||
* Returns a read-only (constant) iterator that points one past the last
|
||||
* pair in the map. Iteration is done in ascending order according to the
|
||||
* keys.
|
||||
*/
|
||||
const_iterator end() const { return _M_t.end(); }
|
||||
|
||||
/**
|
||||
* Returns a read/write reverse iterator that points to the last pair in
|
||||
* the map. Iteration is done in descending order according to the keys.
|
||||
*/
|
||||
reverse_iterator rbegin() { return _M_t.rbegin(); }
|
||||
|
||||
/**
|
||||
* Returns a read-only (constant) reverse iterator that points to the last
|
||||
* pair in the map. Iteration is done in descending order according to
|
||||
* the keys.
|
||||
*/
|
||||
const_reverse_iterator rbegin() const { return _M_t.rbegin(); }
|
||||
|
||||
/**
|
||||
* Returns a read/write reverse iterator that points to one before the
|
||||
* first pair in the map. Iteration is done in descending order according
|
||||
* to the keys.
|
||||
*/
|
||||
reverse_iterator rend() { return _M_t.rend(); }
|
||||
|
||||
/**
|
||||
* Returns a read-only (constant) reverse iterator that points to one
|
||||
* before the first pair in the map. Iteration is done in descending order
|
||||
* according to the keys.
|
||||
*/
|
||||
const_reverse_iterator rend() const { return _M_t.rend(); }
|
||||
|
||||
/** Returns true if the map is empty. (Thus begin() would equal end().) */
|
||||
bool empty() const { return _M_t.empty(); }
|
||||
/** Returns the size of the map. */
|
||||
size_type size() const { return _M_t.size(); }
|
||||
/** Returns the maximum size of the map. */
|
||||
size_type max_size() const { return _M_t.max_size(); }
|
||||
|
||||
/**
|
||||
* @brief Subscript ( [] ) access to map data.
|
||||
* @param k The key for which data should be retrieved.
|
||||
* Allows for easy lookup with the subscript ( [] ) operator. Returns the
|
||||
* data associated with the key specified in subscript. If the key does
|
||||
* not exist a pair with that key is created with a default value, which
|
||||
* is then returned.
|
||||
*/
|
||||
_Tp& operator[](const key_type& __k) {
|
||||
iterator __i = lower_bound(__k);
|
||||
// __i->first is greater than or equivalent to __k.
|
||||
|
|
@ -160,44 +224,216 @@ public:
|
|||
__i = insert(__i, value_type(__k, _Tp()));
|
||||
return (*__i).second;
|
||||
}
|
||||
|
||||
void swap(map<_Key,_Tp,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); }
|
||||
|
||||
// insert/erase
|
||||
|
||||
pair<iterator,bool> insert(const value_type& __x)
|
||||
/**
|
||||
* @brief Attempts to insert a std::pair into the map.
|
||||
* @param x Pair to be inserted (see std::make_pair for easy creation of
|
||||
* pairs).
|
||||
* @return A pair of which the first element is an iterator that points
|
||||
* to the possibly inserted pair, a second element of type bool
|
||||
* to show if the pair was actually inserted.
|
||||
*
|
||||
* This function attempts to insert a (key, value) pair into the map. A
|
||||
* map relies on unique keys and thus a pair is only inserted if its first
|
||||
* element (the key) is not already present in the map.
|
||||
*/
|
||||
pair<iterator,bool> insert(const value_type& __x)
|
||||
{ return _M_t.insert_unique(__x); }
|
||||
|
||||
/**
|
||||
* @brief Attempts to insert a std::pair into the map.
|
||||
* @param position An iterator that serves as a hint as to where the
|
||||
* pair should be inserted.
|
||||
* @param x Pair to be inserted (see std::make_pair for easy creation of
|
||||
* pairs).
|
||||
* @return An iterator that points to the inserted (key,value) pair.
|
||||
*
|
||||
* This function is not concerned about whether the insertion took place
|
||||
* or not and thus does not return a boolean like the single-argument
|
||||
* insert() does. Note that the first parameter is only a hint and can
|
||||
* potentially improve the performance of the insertion process. A bad
|
||||
* hint would cause no gains in efficiency.
|
||||
*/
|
||||
iterator insert(iterator position, const value_type& __x)
|
||||
{ return _M_t.insert_unique(position, __x); }
|
||||
|
||||
/**
|
||||
* @brief A template function that attemps to insert elements from
|
||||
* another range (possibly another map).
|
||||
* @param first Iterator pointing to the start of the range to be inserted.
|
||||
* @param last Iterator pointing to the end of the range.
|
||||
*/
|
||||
template <class _InputIterator>
|
||||
void insert(_InputIterator __first, _InputIterator __last) {
|
||||
_M_t.insert_unique(__first, __last);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Erases an element from a map.
|
||||
* @param position An iterator pointing to the element to be erased.
|
||||
*
|
||||
* This function erases an element, pointed to by the given iterator, from
|
||||
* a map. Note that this function only erases the element, and that if
|
||||
* the element is itself a pointer, the pointed-to memory is not touched
|
||||
* in any way. That is the user's responsibilty.
|
||||
*/
|
||||
void erase(iterator __position) { _M_t.erase(__position); }
|
||||
|
||||
/**
|
||||
* @brief Erases an element according to the provided key.
|
||||
* @param x Key of element to be erased.
|
||||
* @return Doc me!
|
||||
*
|
||||
* This function erases an element, located by the given key, from a map.
|
||||
* Note that this function only erases the element, and that if
|
||||
* the element is itself a pointer, the pointed-to memory is not touched
|
||||
* in any way. That is the user's responsibilty.
|
||||
*/
|
||||
size_type erase(const key_type& __x) { return _M_t.erase(__x); }
|
||||
|
||||
/**
|
||||
* @brief Erases a [first,last) range of elements from a map.
|
||||
* @param first Iterator pointing to the start of the range to be erased.
|
||||
* @param last Iterator pointing to the end of the range to be erased.
|
||||
*
|
||||
* This function erases a sequence of elements from a map.
|
||||
* Note that this function only erases the element, and that if
|
||||
* the element is itself a pointer, the pointed-to memory is not touched
|
||||
* in any way. That is the user's responsibilty.
|
||||
*/
|
||||
void erase(iterator __first, iterator __last)
|
||||
{ _M_t.erase(__first, __last); }
|
||||
|
||||
/** Erases all elements in a map. */
|
||||
void clear() { _M_t.clear(); }
|
||||
|
||||
// map operations:
|
||||
|
||||
/**
|
||||
* @brief Tries to locate an element in a map.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Iterator pointing to sought-after element, or end() if not
|
||||
* found.
|
||||
*
|
||||
* This function takes a key and tries to locate the element with which
|
||||
* the key matches. If successful the function returns an iterator
|
||||
* pointing to the sought after pair. If unsuccessful it returns the
|
||||
* one past the end ( end() ) iterator.
|
||||
*/
|
||||
iterator find(const key_type& __x) { return _M_t.find(__x); }
|
||||
|
||||
/**
|
||||
* @brief Tries to locate an element in a map.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Read-only (constant) iterator pointing to sought-after
|
||||
* element, or end() if not found.
|
||||
*
|
||||
* This function takes a key and tries to locate the element with which
|
||||
* the key matches. If successful the function returns a constant iterator
|
||||
* pointing to the sought after pair. If unsuccessful it returns the
|
||||
* one past the end ( end() ) iterator.
|
||||
*/
|
||||
const_iterator find(const key_type& __x) const { return _M_t.find(__x); }
|
||||
|
||||
/**
|
||||
* @brief Finds the number of elements with given key.
|
||||
* @param x Key of (key, value) pairs to be located.
|
||||
* @return Number of elements with specified key.
|
||||
*
|
||||
* This function only makes sense for multimaps.
|
||||
*/
|
||||
size_type count(const key_type& __x) const {
|
||||
return _M_t.find(__x) == _M_t.end() ? 0 : 1;
|
||||
return _M_t.find(__x) == _M_t.end() ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finds the beginning of a subsequence matching given key.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Iterator pointing to first element matching given key, or
|
||||
* end() if not found.
|
||||
*
|
||||
* This function is useful only with std::multimap. It returns the first
|
||||
* element of a subsequence of elements that matches the given key. If
|
||||
* unsuccessful it returns an iterator pointing to the first element that
|
||||
* has a greater value than given key or end() if no such element exists.
|
||||
*/
|
||||
iterator lower_bound(const key_type& __x) {return _M_t.lower_bound(__x); }
|
||||
|
||||
/**
|
||||
* @brief Finds the beginning of a subsequence matching given key.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Read-only (constant) iterator pointing to first element
|
||||
* matching given key, or end() if not found.
|
||||
*
|
||||
* This function is useful only with std::multimap. It returns the first
|
||||
* element of a subsequence of elements that matches the given key. If
|
||||
* unsuccessful the iterator will point to the next greatest element or,
|
||||
* if no such greater element exists, to end().
|
||||
*/
|
||||
const_iterator lower_bound(const key_type& __x) const {
|
||||
return _M_t.lower_bound(__x);
|
||||
return _M_t.lower_bound(__x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finds the end of a subsequence matching given key.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Iterator pointing to last element matching given key.
|
||||
*
|
||||
* This function only makes sense with multimaps.
|
||||
*/
|
||||
iterator upper_bound(const key_type& __x) {return _M_t.upper_bound(__x); }
|
||||
|
||||
/**
|
||||
* @brief Finds the end of a subsequence matching given key.
|
||||
* @param x Key of (key, value) pair to be located.
|
||||
* @return Read-only (constant) iterator pointing to last element matching
|
||||
* given key.
|
||||
*
|
||||
* This function only makes sense with multimaps.
|
||||
*/
|
||||
const_iterator upper_bound(const key_type& __x) const {
|
||||
return _M_t.upper_bound(__x);
|
||||
return _M_t.upper_bound(__x);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Finds a subsequence matching given key.
|
||||
* @param x Key of (key, value) pairs to be located.
|
||||
* @return Pair of iterators that possibly points to the subsequence
|
||||
* matching given key.
|
||||
*
|
||||
* This function improves on lower_bound() and upper_bound() by giving a more
|
||||
* elegant and efficient solution. It returns a pair of which the first
|
||||
* element possibly points to the first element matching the given key
|
||||
* and the second element possibly points to the last element matching the
|
||||
* given key. If unsuccessful the first element of the returned pair will
|
||||
* contain an iterator pointing to the next greatest element or, if no such
|
||||
* greater element exists, to end().
|
||||
*
|
||||
* This function only makes sense for multimaps.
|
||||
*/
|
||||
pair<iterator,iterator> equal_range(const key_type& __x) {
|
||||
return _M_t.equal_range(__x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finds a subsequence matching given key.
|
||||
* @param x Key of (key, value) pairs to be located.
|
||||
* @return Pair of read-only (constant) iterators that possibly points to
|
||||
* the subsequence matching given key.
|
||||
*
|
||||
* This function improves on lower_bound() and upper_bound() by giving a more
|
||||
* elegant and efficient solution. It returns a pair of which the first
|
||||
* element possibly points to the first element matching the given key
|
||||
* and the second element possibly points to the last element matching the
|
||||
* given key. If unsuccessful the first element of the returned pair will
|
||||
* contain an iterator pointing to the next greatest element or, if no such
|
||||
* a greater element exists, to end().
|
||||
*
|
||||
* This function only makes sense for multimaps.
|
||||
*/
|
||||
pair<const_iterator,const_iterator> equal_range(const key_type& __x) const {
|
||||
return _M_t.equal_range(__x);
|
||||
}
|
||||
|
|
@ -211,43 +447,43 @@ public:
|
|||
};
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return __x._M_t == __y._M_t;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return __x._M_t < __y._M_t;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline bool operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
const map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
template <class _Key, class _Tp, class _Compare, class _Alloc>
|
||||
inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
inline void swap(map<_Key,_Tp,_Compare,_Alloc>& __x,
|
||||
map<_Key,_Tp,_Compare,_Alloc>& __y) {
|
||||
__x.swap(__y);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#include <bits/basic_file.h>
|
||||
#include <bits/gthr.h>
|
||||
|
||||
namespace std
|
||||
namespace std
|
||||
{
|
||||
template<typename _CharT, typename _Traits>
|
||||
class basic_filebuf : public basic_streambuf<_CharT, _Traits>
|
||||
|
|
@ -60,7 +60,7 @@ namespace std
|
|||
typedef typename traits_type::int_type int_type;
|
||||
typedef typename traits_type::pos_type pos_type;
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
|
||||
// Non-standard Types:
|
||||
typedef basic_streambuf<char_type, traits_type> __streambuf_type;
|
||||
typedef basic_filebuf<char_type, traits_type> __filebuf_type;
|
||||
|
|
@ -79,7 +79,7 @@ namespace std
|
|||
|
||||
// Current and beginning state type for codecvt.
|
||||
__state_type _M_state_cur;
|
||||
__state_type _M_state_beg;
|
||||
__state_type _M_state_beg;
|
||||
|
||||
// MT lock inherited from libio or other low-level io library.
|
||||
__c_lock _M_lock;
|
||||
|
|
@ -87,46 +87,46 @@ namespace std
|
|||
// Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
|
||||
bool _M_buf_allocated;
|
||||
|
||||
// XXX Needed?
|
||||
bool _M_last_overflowed;
|
||||
|
||||
// XXX Needed?
|
||||
bool _M_last_overflowed;
|
||||
|
||||
public:
|
||||
// Constructors/destructor:
|
||||
basic_filebuf();
|
||||
|
||||
// Non-standard ctor:
|
||||
basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
|
||||
basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
|
||||
int_type __s = static_cast<int_type>(BUFSIZ));
|
||||
|
||||
|
||||
// Non-standard member:
|
||||
int
|
||||
fd();
|
||||
|
||||
virtual
|
||||
~basic_filebuf()
|
||||
{
|
||||
virtual
|
||||
~basic_filebuf()
|
||||
{
|
||||
this->close();
|
||||
_M_last_overflowed = false;
|
||||
}
|
||||
|
||||
// Members:
|
||||
bool
|
||||
bool
|
||||
is_open(void) const { return _M_file ? _M_file->is_open() : false; }
|
||||
|
||||
__filebuf_type*
|
||||
|
||||
__filebuf_type*
|
||||
open(const char* __s, ios_base::openmode __mode);
|
||||
|
||||
__filebuf_type*
|
||||
|
||||
__filebuf_type*
|
||||
close(void);
|
||||
|
||||
protected:
|
||||
void
|
||||
void
|
||||
_M_allocate_internal_buffer();
|
||||
|
||||
void
|
||||
void
|
||||
_M_destroy_internal_buffer();
|
||||
|
||||
void
|
||||
void
|
||||
_M_allocate_pback_buffer();
|
||||
|
||||
// Create __file_type object and initialize it properly.
|
||||
|
|
@ -134,17 +134,17 @@ namespace std
|
|||
_M_allocate_file();
|
||||
|
||||
// Overridden virtual functions:
|
||||
virtual streamsize
|
||||
virtual streamsize
|
||||
showmanyc(void);
|
||||
|
||||
// Stroustrup, 1998, p. 628
|
||||
|
||||
// Stroustrup, 1998, p. 628
|
||||
// underflow() and uflow() functions are called to get the next
|
||||
// charater from the real input source when the buffer is empty.
|
||||
// Buffered input uses underflow()
|
||||
virtual int_type
|
||||
virtual int_type
|
||||
underflow(void);
|
||||
|
||||
virtual int_type
|
||||
virtual int_type
|
||||
pbackfail(int_type __c = _Traits::eof());
|
||||
|
||||
// NB: For what the standard expects of the overflow function,
|
||||
|
|
@ -155,7 +155,7 @@ namespace std
|
|||
// this in actuality be a helper function that checks for the
|
||||
// eccentricities of this implementation, and then call
|
||||
// overflow() if indeed the buffer is full.
|
||||
virtual int_type
|
||||
virtual int_type
|
||||
overflow(int_type __c = _Traits::eof());
|
||||
|
||||
// Stroustrup, 1998, p 648
|
||||
|
|
@ -163,23 +163,23 @@ namespace std
|
|||
// real output destination when the buffer is full. A call to
|
||||
// overflow(c) outputs the contents of the buffer plus the
|
||||
// character c.
|
||||
// 27.5.2.4.5
|
||||
// 27.5.2.4.5
|
||||
// Consume some sequence of the characters in the pending sequence.
|
||||
int_type
|
||||
int_type
|
||||
_M_really_overflow(int_type __c = _Traits::eof());
|
||||
|
||||
virtual __streambuf_type*
|
||||
|
||||
virtual __streambuf_type*
|
||||
setbuf(char_type* __s, streamsize __n);
|
||||
|
||||
virtual pos_type
|
||||
|
||||
virtual pos_type
|
||||
seekoff(off_type __off, ios_base::seekdir __way,
|
||||
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
||||
|
||||
virtual pos_type
|
||||
virtual pos_type
|
||||
seekpos(pos_type __pos,
|
||||
ios_base::openmode __mode = ios_base::in | ios_base::out);
|
||||
|
||||
virtual int
|
||||
virtual int
|
||||
sync(void)
|
||||
{
|
||||
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
|
||||
|
|
@ -197,14 +197,14 @@ namespace std
|
|||
_M_really_overflow();
|
||||
_M_file->seekpos(__cur + __off);
|
||||
}
|
||||
_M_last_overflowed = false;
|
||||
_M_last_overflowed = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void
|
||||
|
||||
virtual void
|
||||
imbue(const locale& __loc);
|
||||
|
||||
virtual streamsize
|
||||
virtual streamsize
|
||||
xsgetn(char_type* __s, streamsize __n)
|
||||
{
|
||||
streamsize __ret = 0;
|
||||
|
|
@ -224,20 +224,24 @@ namespace std
|
|||
__ret += __streambuf_type::xsgetn(__s, __n - __ret);
|
||||
return __ret;
|
||||
}
|
||||
|
||||
virtual streamsize
|
||||
|
||||
virtual streamsize
|
||||
xsputn(const char_type* __s, streamsize __n)
|
||||
{
|
||||
_M_pback_destroy();
|
||||
return __streambuf_type::xsputn(__s, __n);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_M_output_unshift();
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 27.8.1.5 Template class basic_ifstream
|
||||
/**
|
||||
* Derivation of general input streams, specific to files.
|
||||
*/
|
||||
template<typename _CharT, typename _Traits>
|
||||
class basic_ifstream : public basic_istream<_CharT, _Traits>
|
||||
{
|
||||
|
|
@ -252,52 +256,69 @@ namespace std
|
|||
// Non-standard types:
|
||||
typedef basic_filebuf<char_type, traits_type> __filebuf_type;
|
||||
typedef basic_istream<char_type, traits_type> __istream_type;
|
||||
|
||||
|
||||
private:
|
||||
__filebuf_type _M_filebuf;
|
||||
|
||||
public:
|
||||
// Constructors/Destructors:
|
||||
/** Default constructor. Create an input file stream. */
|
||||
basic_ifstream()
|
||||
: __istream_type(NULL), _M_filebuf()
|
||||
{ this->init(&_M_filebuf); }
|
||||
|
||||
explicit
|
||||
/**
|
||||
* @brief Create an input file stream.
|
||||
* @param s Null terminated string specifying filename.
|
||||
* @param mode Open file in specified mode (see std::ios_base).
|
||||
*
|
||||
* Tip: When using std::string to hold the filename, you must use
|
||||
* .c_str() before passing it to this constructor.
|
||||
*/
|
||||
explicit
|
||||
basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
|
||||
: __istream_type(NULL), _M_filebuf()
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
}
|
||||
|
||||
|
||||
~basic_ifstream()
|
||||
{ }
|
||||
|
||||
// Members:
|
||||
__filebuf_type*
|
||||
rdbuf() const
|
||||
/**
|
||||
* @brief Get a pointer to the file stream's buffer.
|
||||
* @return Pointer to basic_filebuf.
|
||||
*/
|
||||
__filebuf_type*
|
||||
rdbuf() const
|
||||
{ return const_cast<__filebuf_type*>(&_M_filebuf); }
|
||||
|
||||
bool
|
||||
bool
|
||||
is_open(void) { return _M_filebuf.is_open(); }
|
||||
|
||||
void
|
||||
void
|
||||
open(const char* __s, ios_base::openmode __mode = ios_base::in)
|
||||
{
|
||||
{
|
||||
if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
|
||||
this->setstate(ios_base::failbit);
|
||||
this->setstate(ios_base::failbit);
|
||||
}
|
||||
|
||||
void
|
||||
/** Close the file. */
|
||||
void
|
||||
close(void)
|
||||
{
|
||||
{
|
||||
if (!_M_filebuf.close())
|
||||
this->setstate(ios_base::failbit);
|
||||
this->setstate(ios_base::failbit);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 27.8.1.8 Template class basic_ofstream
|
||||
/**
|
||||
* Derivation of general output streams, specific to files.
|
||||
*/
|
||||
template<typename _CharT, typename _Traits>
|
||||
class basic_ofstream : public basic_ostream<_CharT,_Traits>
|
||||
{
|
||||
|
|
@ -312,54 +333,83 @@ namespace std
|
|||
// Non-standard types:
|
||||
typedef basic_filebuf<char_type, traits_type> __filebuf_type;
|
||||
typedef basic_ostream<char_type, traits_type> __ostream_type;
|
||||
|
||||
|
||||
private:
|
||||
__filebuf_type _M_filebuf;
|
||||
|
||||
public:
|
||||
// Constructors:
|
||||
/** Default constructor for output file_stream. */
|
||||
basic_ofstream()
|
||||
: __ostream_type(NULL), _M_filebuf()
|
||||
{ this->init(&_M_filebuf); }
|
||||
|
||||
explicit
|
||||
basic_ofstream(const char* __s,
|
||||
|
||||
/**
|
||||
* @brief Create an output stream.
|
||||
* @param s Null terminated string specifying filename.
|
||||
* @param mode Open file in specified mode (see std::ios_base).
|
||||
*
|
||||
* Tip: When using std::string to hold the filename, you must use
|
||||
* .c_str() before passing it to this constructor.
|
||||
*/
|
||||
explicit
|
||||
basic_ofstream(const char* __s,
|
||||
ios_base::openmode __mode = ios_base::out|ios_base::trunc)
|
||||
: __ostream_type(NULL), _M_filebuf()
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
}
|
||||
|
||||
~basic_ofstream()
|
||||
{ }
|
||||
|
||||
// Members:
|
||||
__filebuf_type*
|
||||
/**
|
||||
* @brief Get a pointer to the file stream's buffer.
|
||||
* @return Pointer to basic_filebuf.
|
||||
*/
|
||||
__filebuf_type*
|
||||
rdbuf(void) const
|
||||
{ return const_cast<__filebuf_type*>(&_M_filebuf); }
|
||||
|
||||
bool
|
||||
|
||||
/**
|
||||
* @brief Query to see if file stream is open.
|
||||
* @return True if stream is open.
|
||||
*/
|
||||
bool
|
||||
is_open(void) { return _M_filebuf.is_open(); }
|
||||
|
||||
void
|
||||
open(const char* __s,
|
||||
/**
|
||||
* @brief Specify a file to open for output.
|
||||
* @param s Null terminated string specifying filename.
|
||||
* @param mode Mode in which to open file (see std::ios_base).
|
||||
*
|
||||
* Tip: When using std::string to hold the filename, you must use
|
||||
* .c_str() before passing it to this constructor.
|
||||
*/
|
||||
void
|
||||
open(const char* __s,
|
||||
ios_base::openmode __mode = ios_base::out | ios_base::trunc)
|
||||
{
|
||||
{
|
||||
if (!_M_filebuf.open(__s, __mode | ios_base::out))
|
||||
this->setstate(ios_base::failbit);
|
||||
this->setstate(ios_base::failbit);
|
||||
}
|
||||
|
||||
void
|
||||
/** Close the file stream. */
|
||||
void
|
||||
close(void)
|
||||
{
|
||||
{
|
||||
if (!_M_filebuf.close())
|
||||
this->setstate(ios_base::failbit);
|
||||
this->setstate(ios_base::failbit);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 27.8.1.11 Template class basic_fstream
|
||||
/**
|
||||
* Derivation of general input/output streams, specific to files.
|
||||
*/
|
||||
template<typename _CharT, typename _Traits>
|
||||
class basic_fstream : public basic_iostream<_CharT, _Traits>
|
||||
{
|
||||
|
|
@ -378,46 +428,72 @@ namespace std
|
|||
|
||||
private:
|
||||
__filebuf_type _M_filebuf;
|
||||
|
||||
|
||||
public:
|
||||
// Constructors/destructor:
|
||||
/** Default constructor. Create a file stream. */
|
||||
basic_fstream()
|
||||
: __iostream_type(NULL), _M_filebuf()
|
||||
{ this->init(&_M_filebuf); }
|
||||
|
||||
explicit
|
||||
/**
|
||||
* @brief Create an input/output stream.
|
||||
* @param s Null terminated string specifying filename.
|
||||
* @param mode Open file in specified mode (see std::ios_base).
|
||||
*
|
||||
* Tip: When using std::string to hold the filename, you must use
|
||||
* .c_str() before passing it to this constructor.
|
||||
*/
|
||||
explicit
|
||||
basic_fstream(const char* __s,
|
||||
ios_base::openmode __mode = ios_base::in | ios_base::out)
|
||||
: __iostream_type(NULL), _M_filebuf()
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
{
|
||||
this->init(&_M_filebuf);
|
||||
this->open(__s, __mode);
|
||||
}
|
||||
|
||||
|
||||
~basic_fstream()
|
||||
{ }
|
||||
|
||||
|
||||
// Members:
|
||||
__filebuf_type*
|
||||
rdbuf(void) const
|
||||
/**
|
||||
* @brief Get a pointer to the file stream's buffer.
|
||||
* @return Pointer to basic_filebuf.
|
||||
*/
|
||||
__filebuf_type*
|
||||
rdbuf(void) const
|
||||
{ return const_cast<__filebuf_type*>(&_M_filebuf); }
|
||||
|
||||
bool
|
||||
/**
|
||||
* @brief Query to see if file stream is open.
|
||||
* @return True if stream is open.
|
||||
*/
|
||||
bool
|
||||
is_open(void) { return _M_filebuf.is_open(); }
|
||||
|
||||
void
|
||||
open(const char* __s,
|
||||
/**
|
||||
* @brief Specify a file to open for input and/or output.
|
||||
* @param s Null terminated string specifying filename.
|
||||
* @param mode Mode in which to open file (see std::ios_base).
|
||||
*
|
||||
* Tip: When using std::string to hold the filename, you must use
|
||||
* .c_str() before passing it to this constructor.
|
||||
*/
|
||||
void
|
||||
open(const char* __s,
|
||||
ios_base::openmode __mode = ios_base::in | ios_base::out)
|
||||
{
|
||||
{
|
||||
if (!_M_filebuf.open(__s, __mode))
|
||||
setstate(ios_base::failbit);
|
||||
setstate(ios_base::failbit);
|
||||
}
|
||||
|
||||
void
|
||||
/** Close the file stream. */
|
||||
void
|
||||
close(void)
|
||||
{
|
||||
{
|
||||
if (!_M_filebuf.close())
|
||||
setstate(ios_base::failbit);
|
||||
setstate(ios_base::failbit);
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
|
@ -429,4 +505,4 @@ namespace std
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue