twa_run: keep a pointer to the automaton
This simplify all laters invocations, because we do not have to pass the automaton the run was generated on. This fixes #113 by allowing the __str__ function to be implemented on runs. * src/twaalgos/emptiness.cc, src/twaalgos/emptiness.hh (twa_run): Store the automaton. (prin_twa_run): Rewrite as an overloaded <<. * src/twaalgos/reducerun.cc, src/twaalgos/reducerun.hh (reduce_run): Do not like the automaton as a parameter. * src/twaalgos/replayrun.cc, src/twaalgos/replayrun.hh (replay_twa_run): Likewise. * src/bin/common_aoutput.hh, src/bin/ltlcross.cc, src/tests/complementation.cc, src/tests/ikwiad.cc, src/tests/randtgba.cc, src/twaalgos/gtec/ce.cc, src/twaalgos/gv04.cc, src/twaalgos/magic.cc, src/twaalgos/ndfs_result.hxx, src/twaalgos/se05.cc, src/twaalgos/projrun.cc: Adjust. * wrap/python/ajax/spotcgi.in: Add a __str__ function to twa_run_ptr. * wrap/python/spot_impl.i: Adjust.
This commit is contained in:
parent
e7cc89264a
commit
63917def2d
19 changed files with 85 additions and 97 deletions
|
|
@ -179,7 +179,7 @@ public:
|
||||||
{
|
{
|
||||||
auto run = res->accepting_run();
|
auto run = res->accepting_run();
|
||||||
assert(run);
|
assert(run);
|
||||||
run = reduce_run(aut, run);
|
run = reduce_run(run);
|
||||||
spot::tgba_word w(run);
|
spot::tgba_word w(run);
|
||||||
w.simplify();
|
w.simplify();
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
|
||||||
|
|
@ -703,7 +703,7 @@ namespace
|
||||||
auto run = res->accepting_run();
|
auto run = res->accepting_run();
|
||||||
if (run)
|
if (run)
|
||||||
{
|
{
|
||||||
run = reduce_run(prod, run);
|
run = reduce_run(run);
|
||||||
std::cerr << "; both automata accept the infinite word\n"
|
std::cerr << "; both automata accept the infinite word\n"
|
||||||
<< " ";
|
<< " ";
|
||||||
spot::tgba_word w(run);
|
spot::tgba_word w(run);
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ int main(int argc, char* argv[])
|
||||||
if (auto run = res->accepting_run())
|
if (auto run = res->accepting_run())
|
||||||
{
|
{
|
||||||
spot::print_dot(std::cout, ec->automaton());
|
spot::print_dot(std::cout, ec->automaton());
|
||||||
spot::print_twa_run(std::cout, ec->automaton(), run);
|
std::cout << run;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1580,14 +1580,13 @@ checked_main(int argc, char** argv)
|
||||||
if (opt_reduce)
|
if (opt_reduce)
|
||||||
{
|
{
|
||||||
tm.start("reducing accepting run");
|
tm.start("reducing accepting run");
|
||||||
run = spot::reduce_run(res->automaton(), run);
|
run = spot::reduce_run(run);
|
||||||
tm.stop("reducing accepting run");
|
tm.stop("reducing accepting run");
|
||||||
}
|
}
|
||||||
if (accepting_run_replay)
|
if (accepting_run_replay)
|
||||||
{
|
{
|
||||||
tm.start("replaying acc. run");
|
tm.start("replaying acc. run");
|
||||||
if (!spot::replay_twa_run(std::cout, a,
|
if (!spot::replay_twa_run(std::cout, run, true))
|
||||||
run, true))
|
|
||||||
exit_code = 1;
|
exit_code = 1;
|
||||||
tm.stop("replaying acc. run");
|
tm.stop("replaying acc. run");
|
||||||
}
|
}
|
||||||
|
|
@ -1601,7 +1600,7 @@ checked_main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spot::print_twa_run(std::cout, a, run);
|
std::cout << run;
|
||||||
}
|
}
|
||||||
tm.stop("printing accepting run");
|
tm.stop("printing accepting run");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1026,9 +1026,7 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
tm_ar.stop(algo);
|
tm_ar.stop(algo);
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
if (!spot::replay_twa_run(s,
|
if (!spot::replay_twa_run(s, run))
|
||||||
res->automaton(),
|
|
||||||
run))
|
|
||||||
{
|
{
|
||||||
if (!opt_paper)
|
if (!opt_paper)
|
||||||
std::cout << ", but could not replay "
|
std::cout << ", but could not replay "
|
||||||
|
|
@ -1049,12 +1047,8 @@ main(int argc, char** argv)
|
||||||
|
|
||||||
if (opt_reduce)
|
if (opt_reduce)
|
||||||
{
|
{
|
||||||
auto redrun =
|
auto redrun = spot::reduce_run(run);
|
||||||
spot::reduce_run(res->automaton(), run);
|
if (!spot::replay_twa_run(s, redrun))
|
||||||
if (!spot::replay_twa_run(s,
|
|
||||||
res
|
|
||||||
->automaton(),
|
|
||||||
redrun))
|
|
||||||
{
|
{
|
||||||
if (!opt_paper)
|
if (!opt_paper)
|
||||||
std::cout
|
std::cout
|
||||||
|
|
|
||||||
|
|
@ -47,16 +47,15 @@ namespace spot
|
||||||
|
|
||||||
twa_run::twa_run(const twa_run& run)
|
twa_run::twa_run(const twa_run& run)
|
||||||
{
|
{
|
||||||
for (steps::const_iterator i = run.prefix.begin();
|
aut = run.aut;
|
||||||
i != run.prefix.end(); ++i)
|
for (step s : run.prefix)
|
||||||
{
|
{
|
||||||
step s = { i->s->clone(), i->label, i->acc };
|
s.s = s.s->clone();
|
||||||
prefix.push_back(s);
|
prefix.push_back(s);
|
||||||
}
|
}
|
||||||
for (steps::const_iterator i = run.cycle.begin();
|
for (step s : run.cycle)
|
||||||
i != run.cycle.end(); ++i)
|
|
||||||
{
|
{
|
||||||
step s = { i->s->clone(), i->label, i->acc };
|
s.s = s.s->clone();
|
||||||
cycle.push_back(s);
|
cycle.push_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,37 +71,27 @@ namespace spot
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print_twa_run
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
print_twa_run(std::ostream& os,
|
operator<<(std::ostream& os, const twa_run_ptr& run)
|
||||||
const const_twa_ptr& a,
|
|
||||||
const const_twa_run_ptr& run)
|
|
||||||
{
|
{
|
||||||
|
auto& a = run->aut;
|
||||||
bdd_dict_ptr d = a->get_dict();
|
bdd_dict_ptr d = a->get_dict();
|
||||||
os << "Prefix:" << std::endl;
|
|
||||||
for (twa_run::steps::const_iterator i = run->prefix.begin();
|
auto pstep = [&](const twa_run::step& st)
|
||||||
i != run->prefix.end(); ++i)
|
|
||||||
{
|
{
|
||||||
os << " " << a->format_state(i->s) << std::endl;
|
os << " " << a->format_state(st.s) << "\n | ";
|
||||||
os << " | ";
|
bdd_print_formula(os, d, st.label);
|
||||||
bdd_print_formula(os, d, i->label);
|
if (st.acc)
|
||||||
os << '\t';
|
os << '\t' << st.acc;
|
||||||
os << a->acc().format(i->acc);
|
|
||||||
os << std::endl;
|
|
||||||
}
|
|
||||||
os << "Cycle:" << std::endl;
|
|
||||||
for (twa_run::steps::const_iterator i = run->cycle.begin();
|
|
||||||
i != run->cycle.end(); ++i)
|
|
||||||
{
|
|
||||||
os << " " << a->format_state(i->s) << std::endl;
|
|
||||||
os << " | ";
|
|
||||||
bdd_print_formula(os, d, i->label);
|
|
||||||
os << '\t';
|
|
||||||
os << a->acc().format(i->acc);
|
|
||||||
os << '\n';
|
os << '\n';
|
||||||
}
|
};
|
||||||
|
|
||||||
|
os << "Prefix:" << std::endl;
|
||||||
|
for (auto& s: run->prefix)
|
||||||
|
pstep(s);
|
||||||
|
os << "Cycle:" << std::endl;
|
||||||
|
for (auto& s: run->cycle)
|
||||||
|
pstep(s);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,13 +257,12 @@ namespace spot
|
||||||
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
|
/// \addtogroup emptiness_check_algorithms Emptiness-check algorithms
|
||||||
/// \ingroup emptiness_check
|
/// \ingroup emptiness_check
|
||||||
|
|
||||||
|
/// \addtogroup twa_run TωA runs and supporting functions
|
||||||
/// \addtogroup twa_run TGBA runs and supporting functions
|
|
||||||
/// \ingroup emptiness_check
|
/// \ingroup emptiness_check
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// An accepted run, for a tgba.
|
/// An accepted run, for a twa.
|
||||||
struct SPOT_API twa_run
|
struct SPOT_API twa_run final
|
||||||
{
|
{
|
||||||
struct step {
|
struct step {
|
||||||
const state* s;
|
const state* s;
|
||||||
|
|
@ -283,33 +282,34 @@ namespace spot
|
||||||
|
|
||||||
steps prefix;
|
steps prefix;
|
||||||
steps cycle;
|
steps cycle;
|
||||||
|
const_twa_ptr aut;
|
||||||
|
|
||||||
~twa_run();
|
~twa_run();
|
||||||
twa_run()
|
twa_run(const const_twa_ptr& aut)
|
||||||
|
: aut(aut)
|
||||||
{
|
{
|
||||||
};
|
}
|
||||||
twa_run(const twa_run& run);
|
twa_run(const twa_run& run);
|
||||||
twa_run& operator=(const twa_run& run);
|
twa_run& operator=(const twa_run& run);
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief Display a twa_run.
|
/// \brief Display a twa_run.
|
||||||
///
|
///
|
||||||
/// Output the prefix and cycle parts of the twa_run \a run on \a os.
|
/// Output the prefix and cycle parts of the twa_run \a run on \a os.
|
||||||
///
|
///
|
||||||
/// The automaton \a a is used only to format the states, and
|
/// The automaton object (stored by \a run) is used only to format
|
||||||
/// to know how to print the BDDs describing the conditions and
|
/// the states, and to know how to print the BDDs describing the
|
||||||
/// acceptance conditions of the run; it is <b>not</b> used to
|
/// conditions and acceptance conditions of the run; it is
|
||||||
/// replay the run. In other words this function will work even if
|
/// <b>not</b> used to replay the run. In other words this
|
||||||
/// the twa_run you are trying to print appears to connect states
|
/// function will work even if the twa_run you are trying to print
|
||||||
/// of \a a that are not connected.
|
/// appears to connect states that are not connected.
|
||||||
///
|
///
|
||||||
/// This is unlike replay_twa_run(), which will ensure the run
|
/// This is unlike replay_twa_run(), which will ensure the run
|
||||||
/// actually exists in the automaton (and will also display any
|
/// actually exists in the automaton (and will also display any
|
||||||
/// transition annotation).
|
/// transition annotation).
|
||||||
SPOT_API std::ostream&
|
SPOT_API
|
||||||
print_twa_run(std::ostream& os,
|
friend std::ostream& operator<<(std::ostream& os, const twa_run_ptr& run);
|
||||||
const const_twa_ptr& a,
|
};
|
||||||
const const_twa_run_ptr& run);
|
|
||||||
|
|
||||||
/// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable
|
/// \brief Return an explicit_tgba corresponding to \a run (i.e. comparable
|
||||||
/// states are merged).
|
/// states are merged).
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ namespace spot
|
||||||
twa_run_ptr
|
twa_run_ptr
|
||||||
couvreur99_check_result::accepting_run()
|
couvreur99_check_result::accepting_run()
|
||||||
{
|
{
|
||||||
run_ = std::make_shared<twa_run>();
|
run_ = std::make_shared<twa_run>(ecs_->aut);
|
||||||
|
|
||||||
assert(!ecs_->root.empty());
|
assert(!ecs_->root.empty());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@ namespace spot
|
||||||
virtual twa_run_ptr
|
virtual twa_run_ptr
|
||||||
accepting_run()
|
accepting_run()
|
||||||
{
|
{
|
||||||
auto res = std::make_shared<twa_run>();
|
auto res = std::make_shared<twa_run>(automaton());
|
||||||
|
|
||||||
update_lowlinks();
|
update_lowlinks();
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@ namespace spot
|
||||||
assert(!ms_->st_blue.empty());
|
assert(!ms_->st_blue.empty());
|
||||||
assert(!ms_->st_red.empty());
|
assert(!ms_->st_red.empty());
|
||||||
|
|
||||||
auto run = std::make_shared<twa_run>();
|
auto run = std::make_shared<twa_run>(automaton());
|
||||||
|
|
||||||
typename stack_type::const_reverse_iterator i, j, end;
|
typename stack_type::const_reverse_iterator i, j, end;
|
||||||
twa_run::steps* l;
|
twa_run::steps* l;
|
||||||
|
|
|
||||||
|
|
@ -194,7 +194,7 @@ namespace spot
|
||||||
|
|
||||||
assert(!acc_trans.empty());
|
assert(!acc_trans.empty());
|
||||||
|
|
||||||
auto run = std::make_shared<twa_run>();
|
auto run = std::make_shared<twa_run>(automaton());
|
||||||
// construct run->cycle from acc_trans.
|
// construct run->cycle from acc_trans.
|
||||||
construct_cycle(run, acc_trans);
|
construct_cycle(run, acc_trans);
|
||||||
// construct run->prefix (a minimal path from the initial state to any
|
// construct run->prefix (a minimal path from the initial state to any
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace spot
|
||||||
const const_twa_ptr& a_proj,
|
const const_twa_ptr& a_proj,
|
||||||
const const_twa_run_ptr& run)
|
const const_twa_run_ptr& run)
|
||||||
{
|
{
|
||||||
auto res = std::make_shared<twa_run>();
|
auto res = std::make_shared<twa_run>(a_proj);
|
||||||
for (auto& i: run->prefix)
|
for (auto& i: run->prefix)
|
||||||
res->prefix.emplace_back(a_run->project_state(i.s, a_proj),
|
res->prefix.emplace_back(a_run->project_state(i.s, a_proj),
|
||||||
i.label, i.acc);
|
i.label, i.acc);
|
||||||
|
|
|
||||||
|
|
@ -88,9 +88,10 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
twa_run_ptr
|
twa_run_ptr
|
||||||
reduce_run(const const_twa_ptr& a, const const_twa_run_ptr& org)
|
reduce_run(const const_twa_run_ptr& org)
|
||||||
{
|
{
|
||||||
auto res = std::make_shared<twa_run>();
|
auto& a = org->aut;
|
||||||
|
auto res = std::make_shared<twa_run>(a);
|
||||||
state_set ss;
|
state_set ss;
|
||||||
shortest_path shpath(a);
|
shortest_path shpath(a);
|
||||||
shpath.set_target(&ss);
|
shpath.set_target(&ss);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2010, 2013, 2014 Laboratoire de Recherche et
|
// Copyright (C) 2010, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita.
|
// Développement de l'Epita.
|
||||||
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -31,8 +31,8 @@ namespace spot
|
||||||
/// \ingroup twa_run
|
/// \ingroup twa_run
|
||||||
/// \brief Reduce an accepting run.
|
/// \brief Reduce an accepting run.
|
||||||
///
|
///
|
||||||
/// Return a run which is accepting for \a a and that is no longer
|
/// Return a run which is still accepting for <code>org->aut</code>,
|
||||||
/// than \a org.
|
/// but is no longer than \a org.
|
||||||
SPOT_API twa_run_ptr
|
SPOT_API twa_run_ptr
|
||||||
reduce_run(const const_twa_ptr& a, const const_twa_run_ptr& org);
|
reduce_run(const const_twa_run_ptr& org);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2011, 2013, 2014 Laboratoire de Recherche et
|
// Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -44,9 +44,10 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
replay_twa_run(std::ostream& os, const const_twa_ptr& a,
|
replay_twa_run(std::ostream& os,
|
||||||
const const_twa_run_ptr& run, bool debug)
|
const const_twa_run_ptr& run, bool debug)
|
||||||
{
|
{
|
||||||
|
auto& a = run->aut;
|
||||||
const state* s = a->get_init_state();
|
const state* s = a->get_init_state();
|
||||||
int serial = 1;
|
int serial = 1;
|
||||||
const twa_run::steps* l;
|
const twa_run::steps* l;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013, 2014 Laboratoire de Recherche et Developpement
|
// Copyright (C) 2013, 2014, 2015 Laboratoire de Recherche et Developpement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
// Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -34,21 +34,19 @@ namespace spot
|
||||||
/// \ingroup twa_run
|
/// \ingroup twa_run
|
||||||
/// \brief Replay a twa_run on a tgba.
|
/// \brief Replay a twa_run on a tgba.
|
||||||
///
|
///
|
||||||
/// This is similar to print_twa_run(), except that the run is
|
/// This is similar to <code>os << run;</code>, except that the run is
|
||||||
/// actually replayed on the automaton while it is printed. Doing
|
/// actually replayed on the automaton while it is printed. Doing
|
||||||
/// so makes it possible to display transition annotations (returned
|
/// so makes it possible to display transition annotations (returned
|
||||||
/// by spot::tgba::transition_annotation()). The output will stop
|
/// by spot::twa::transition_annotation()). The output will stop
|
||||||
/// if the run cannot be completed.
|
/// if the run cannot be completed.
|
||||||
///
|
///
|
||||||
/// \param run the run to replay
|
/// \param run the run to replay
|
||||||
/// \param a the automata on which to replay that run
|
|
||||||
/// \param os the stream on which the replay should be traced
|
/// \param os the stream on which the replay should be traced
|
||||||
/// \param debug if set the output will be more verbose and extra
|
/// \param debug if set the output will be more verbose and extra
|
||||||
/// debugging informations will be output on failure
|
/// debugging informations will be output on failure
|
||||||
/// \return true iff the run could be completed
|
/// \return true iff the run could be completed
|
||||||
SPOT_API bool
|
SPOT_API bool
|
||||||
replay_twa_run(std::ostream& os,
|
replay_twa_run(std::ostream& os,
|
||||||
const const_twa_ptr& a,
|
|
||||||
const const_twa_run_ptr& run,
|
const const_twa_run_ptr& run,
|
||||||
bool debug = false);
|
bool debug = false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,7 @@ namespace spot
|
||||||
assert(!ms_->st_blue.empty());
|
assert(!ms_->st_blue.empty());
|
||||||
assert(!ms_->st_red.empty());
|
assert(!ms_->st_red.empty());
|
||||||
|
|
||||||
auto run = std::make_shared<twa_run>();
|
auto run = std::make_shared<twa_run>(automaton());
|
||||||
|
|
||||||
typename stack_type::const_reverse_iterator i, j, end;
|
typename stack_type::const_reverse_iterator i, j, end;
|
||||||
twa_run::steps* l;
|
twa_run::steps* l;
|
||||||
|
|
|
||||||
|
|
@ -840,11 +840,8 @@ if output_type == 'r':
|
||||||
unbufprint('<div class="ec">An accepting run was found.<br/>')
|
unbufprint('<div class="ec">An accepting run was found.<br/>')
|
||||||
if ec_run:
|
if ec_run:
|
||||||
if print_acc_run:
|
if print_acc_run:
|
||||||
s = spot.ostringstream()
|
|
||||||
spot.print_twa_run(s, ec_a, ec_run)
|
|
||||||
unbufprint('<div class="accrun">%s</div>' %
|
unbufprint('<div class="accrun">%s</div>' %
|
||||||
cgi.escape(s.str()))
|
cgi.escape(str(ec_run)))
|
||||||
del s
|
|
||||||
if draw_acc_run:
|
if draw_acc_run:
|
||||||
render_automaton(spot.twa_run_to_tgba(ec_a, ec_run), False)
|
render_automaton(spot.twa_run_to_tgba(ec_a, ec_run), False)
|
||||||
del ec_run
|
del ec_run
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,15 @@ namespace std {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%extend spot::twa_run_ptr {
|
||||||
|
std::string __str__()
|
||||||
|
{
|
||||||
|
std::ostringstream os;
|
||||||
|
os << *self;
|
||||||
|
return os.str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
%nodefaultctor std::ostream;
|
%nodefaultctor std::ostream;
|
||||||
namespace std {
|
namespace std {
|
||||||
class ostream {};
|
class ostream {};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue