Is it possible to execute "cout" by order? - c++

Is it possible to get the raw output as shown but with specific order(from bottom to top)?
cout<<R"(programming )";sleep(10); cout<<R"(
newbie at )";sleep(5); cout<<R"(
i'm )"; sleep(1);
output: programming------>printed third at the first line
newbie at------->printed second at the second line
i'm--------->printed first at the third line
Note: I don't mean reversing the output.
edit: as I guess the simple trick is to set their colour to black which will make them "disappear" and then by using nested for loop I can move through lines and change the colour of their one by one to white again with delay but i dont have an idea about how to do it practically

#include <chrono>
#include <future>
#include <iostream>
#include <thread>
int main()
{
using namespace std::chrono_literals;
auto print_first_line = std::async(std::launch::async, []() {
std::this_thread::sleep_for(6s);
std::cout << "programming\n" << std::flush;
});
auto print_second_line = std::async(std::launch::async, []() {
std::this_thread::sleep_for(3s);
std::cout << "newbie at\n" << std::flush;
});
auto print_third_line = std::async(std::launch::async, []() {
std::this_thread::sleep_for(1s);
std::cout << "i'm\n" << std::flush;
});
print_first_line.wait();
print_second_line.wait();
print_third_line.wait();
return 0;
}
As stated in the comments, it is not possible to control std::cout in this way. But it is possible to use threads to control the timing for you. This is a quick & dirty example of using std::async from <future> to multi-thread your print statements.
The first argument to std::async explicitly tells it to launch asynchronously as it can launch without creating a new thread. The second argument is a lambda with the sleep timer and the print statement.
It is worth noting that you will likely need an additional compiler argument. My current testing is in the WSL (Debian), so the compile command I'm using is clang++ -Wall -Wextra -pthread main.cpp where -pthread is the argument enabling multi-threading. For your platform it may be different.
As suggested, this scenario might be better served with a more generic function; something like delay_print(). Here's a possible implementation.
#include <array>
#include <chrono>
#include <cstdint>
#include <future>
#include <iostream>
#include <string>
#include <thread>
void delay_print(const std::chrono::duration<std::int64_t> &time,
std::string message)
{
std::this_thread::sleep_for(time);
std::cout << message << std::flush;
}
int main()
{
using namespace std::chrono_literals;
std::array<int, 4> seconds{7, 4, 2, 1};
std::array<std::string, 4> phrases{"How\n", "Now\n", "Brown\n", "Cow\n"};
auto print_line_01 =
std::async(std::launch::async, &delay_print,
std::chrono::seconds(seconds[0]), phrases[0]);
auto print_line_02 =
std::async(std::launch::async, &delay_print,
std::chrono::seconds(seconds[1]), phrases[1]);
auto print_line_03 =
std::async(std::launch::async, &delay_print,
std::chrono::seconds(seconds[2]), phrases[2]);
auto print_line_04 =
std::async(std::launch::async, &delay_print,
std::chrono::seconds(seconds[3]), phrases[3]);
print_line_01.wait();
print_line_02.wait();
print_line_03.wait();
print_line_04.wait();
return 0;
}

Related

clang++ compiler is hanging with -std=c++17 -O3

I am using this command line to compile my program.
clang++ -std=c++17 -O3 main.cpp -o main
I have started the compiler 20 minutes ago, and it is just hanging. I terminate the compiler, and try to compile it again and it is still hanging. If I use the exact same command line, but without the -O3 the compiler completes instantly, but with the -O3 it is hanging.
The code that it is compiling is relatively simple, without any errors. What is going on?
#include <ctime> // for time()
#include <cstdlib> // for srand(), rand(), size_t, EXIT_SUCCESS
#include <iostream>
#include <string>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
int main()
{
vector<string> messages;
messages.push_back(string("“Blessed are those who are persecuted because of righteousness, for theirs is the kingdom of heaven.”"));
messages.push_back(string("“Let the little children come to me, and do not hinder them, for the kingdom of heaven belongs to such as these.”"));
/* Literally 10000 more quotes from the Bible. */
srand(time(NULL));
cout << messages[ rand() % messages.size() ] << endl;
return EXIT_SUCCESS;
}
What is going on?
If you want to keep all the strings in the program (instead of reading them from a file) I would replace the std::vector<std::string> with a const std::vector<std::string_view> or maybe even a const std::vector<const char*> and initialize it with all the strings:
#include <ctime> // for time()
#include <cstdlib> // for srand(), rand(), size_t, EXIT_SUCCESS
#include <iostream>
#include <string_view>
#include <vector>
int main() {
const std::vector<std::string_view> messages{
"“Blessed are those who are persecuted because of righteousness, for theirs is the kingdom of heaven.”",
"“Let the little children come to me, and do not hinder them, for the kingdom of heaven belongs to such as these.”",
/* Literally 10000 more quotes from the Bible. */
};
srand(time(NULL));
std::cout << messages[ rand() % messages.size() ] << '\n';
}
I wasn't patient enough to wait for the compiler to finish compiling your original code. The above compiled in ~1 second.
Note: There's a <random> header which gives you access to much better pseudo random number generation than rand(). You should look into using that instead. The end of your program would look like something like this using that:
std::mt19937 prng(std::random_device{}());
std::uniform_int_distribution<std::size_t> dist(0, messages.size() - 1);
std::cout << messages[ dist(prng) ] << '\n';

Why doesn't std::execution::par launch threads with std::views::iota iterators

Here are two version of the code. One uses std::vector iterators in the std::for_each call, the other uses the std::views::iota iterators.
I expect both of these to use multiple threads, since I'm using std::execution::par, but it appears like that isn't the case. The iota version only uses a single thread and I don't understand why.
Vector version
#include <algorithm>
#include <execution>
#include <iostream>
#include <mutex>
#include <ranges>
#include <thread>
#include <vector>
int main()
{
std::mutex io_mutex;
auto offsets0_ = std::views::iota(0, 8);
auto offsets0 = std::vector<int>(std::begin(offsets0_), std::end(offsets0_));
std::for_each(
std::execution::par,
std::begin(offsets0), std::end(offsets0),
[&](auto offset0) {
io_mutex.lock();
std::cout << std::this_thread::get_id() << ": " << offset0 << '\n';
// Emulate doing a bunch of work, otherwise threads don't spawn in either scenario
std::this_thread::sleep_for(std::chrono::milliseconds(200));
io_mutex.unlock();
});
}
Output
139803706330688: 0
139803706330688: 1
139803695208000: 6
139803691009600: 5
139803699406400: 4
139803706330688: 2
139803695208000: 7
139803691009600: 3
So it used 4 threads to go through all items. My PC has 4 cores, so that makes sense.
Iota ranges version
#include <algorithm>
#include <execution>
#include <iostream>
#include <mutex>
#include <ranges>
#include <thread>
#include <vector>
int main()
{
std::mutex io_mutex;
auto offsets0 = std::views::iota(0, 8);
std::for_each(
std::execution::par,
std::begin(offsets0), std::end(offsets0),
[&](auto offset0) {
io_mutex.lock();
std::cout << std::this_thread::get_id() << ": " << offset0 << '\n';
// Emulate doing a bunch of work, otherwise threads don't spawn in either scenario
std::this_thread::sleep_for(std::chrono::milliseconds(200));
io_mutex.unlock();
});
}
output
139954983456320: 0
139954983456320: 1
139954983456320: 2
139954983456320: 3
139954983456320: 4
139954983456320: 5
139954983456320: 6
139954983456320: 7
With the iota ranges iterators it only a single thread.. Why? are ranges not supposed to be used like this?
Both of these were compiled with these options: g++ main.cpp -std=c++20 -ltbb -O3. Using gcc 11.1.0, glibc 2.33, and tbb 2020.3.
As per cppreference, this is the signature of for_each with the execution policy parameter.
template< class ExecutionPolicy, class ForwardIt, class UnaryFunction2 >
void for_each( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, UnaryFunction2 f );
Where ForwardIt should satisfy the LegacyForwardIterator requirements.
But iota_view::iterator only goes up to LegacyInputIterator when the value_type is 'incrementable', from my understanding it never satisfies LegacyForwardIterator. cppreference
This is probably why the for_each call doesn't do what you'd expect.
I'm not sure why it's not just a compilation error, maybe it's intentional, though it does feel unusual to completely ignore the execution policy. I hope another answer can shed light on this.

Prevent usage of a third-party base class

I have implemented my own wrapper around std::chrono::steady_clock and would like to prevent any other developer from using the original:
#include <iostream>
#include <chrono>
namespace my_chrono {
class MyClock : public std::chrono::steady_clock {
// stuff here...
};
}
int main()
{
auto my_now = my_chrono::MyClock::now(); // this should compile
auto chrono_now = std::chrono::steady_clock::now(); // this should be prevented
std::cout << my_now.time_since_epoch().count() << ", " << chrono_now.time_since_epoch().count() << std::endl;
return 0;
}
Unfortunately, I cannot find a way to force usage of MyClock over steady_clock (for example via compiler errors or warnings treated as errors).
You cannot make it impossible for some other code to be unable to use something you have no control over. And the C++ standard library is something over which you have no control.

c++ iterate through a vector of strings

So I recently discovered the use of map and vectors, however, I'm having trouble of trying to figure a way to loop through a vector containing strings.
Here's what I've tried:
#include <string>
#include <vector>
#include <stdio>
using namespace std;
void main() {
vector<string> data={"Hello World!","Goodbye World!"};
for (vector<string>::iterator t=data.begin(); t!=data.end(); ++t) {
cout<<*t<<endl;
}
}
and when I try to compile it, I get this error:
cd C:\Users\Jason\Desktop\EXB\Win32
wmake -f C:\Users\Jason\Desktop\EXB\Win32\exbint.mk -h -e
wpp386 ..\Source\exbint.cpp -i="C:\WATCOM/h;C:\WATCOM/h/nt" -w4 -e25 -zq -od -d2 -6r -bt=nt -fo=.obj -mf -xs -xr
..\Source\exbint.cpp(59): Error! E157: col(21) left expression must be integral
..\Source\exbint.cpp(59): Note! N717: col(21) left operand type is 'std::ostream watcall (lvalue)'
..\Source\exbint.cpp(59): Note! N718: col(21) right operand type is 'std::basic_string<char,std::char_traits<char>,std::allocator<char>> (lvalue)'
Error(E42): Last command making (C:\Users\Jason\Desktop\EXB\Win32\exbint.obj) returned a bad status
Error(E02): Make execution terminated
Execution complete
I tried the same method using map and it worked. The only difference was I changed the cout line to:
cout<<t->first<<" => "<<t->last<<endl;
Add iostream header file and change stdio to cstdio.
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
using namespace std;
int main()
{
vector<string> data={"Hello World!","Goodbye World!"};
for (vector<string>::iterator t=data.begin(); t!=data.end(); ++t)
{
cout<<*t<<endl;
}
return 0;
}
#include <iostream>
#include <vector>
#include <string>
int main()
{
std::vector<std::string> data = {"Hello World!", "Goodbye World!"};
for (std::vector<std::string>::iterator t = data.begin(); t != data.end(); t++) {
std::cout << *t << std::endl;
}
return 0;
}
Or with C++11 (or higher):
#include <iostream>
#include <vector>
#include <string>
typedef std::vector<std::string> STRVEC;
int main()
{
STRVEC data = {"Hello World!", "Goodbye World!"};
for (auto &s: data) {
std::cout << s << std::endl;
}
return 0;
}
From the Open Watcom V2 Fork-Wiki on the C++ Library Status page:
<string>
Mostly complete. Although there are no I/O operators, all other member functions and string operations are available.
A workaround (besides implementing the << operator) would be asking the string instances for the C string:
for (vector<string>::iterator t = data.begin(); t != data.end(); ++t) {
cout << t->c_str() << endl;
}
This of course only works as long as the strings don't contain zero byte values.
When I compile your code, I get:
40234801.cpp:3:17: fatal error: stdio: No such file or directory
#include <stdio>
^
You clearly have a header called "stdio" in your include path that you haven't shown us.
If you change that line to the standard #include <iostream>, then the only reported error is that you wrote void main() instead of int main(). Fix that, and it will build and run.
In passing, note also that using namespace should be avoided.
I found a solution to my own issue. Instead of using a c_str, I used std::string and switched to using the G++ compiler instead of Open Watcom
Instead of having:
char *someString="Blah blah blah";
I instead replaced it with:
string someString="Blah blah blah";
This way is much more efficient and easier.

Bind a boost signal with phoenix bind

I am using boost spirit qi to parse inbound data then dispatch the correct functionality depending on it's content.
I am using boost::signals to manage the callbacks; my problem is that I don't seem to be able to use phoenix bind with the boost signals.
Consider the following test case:
#include <boost/signals.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <iostream>
void f(int i) {
std::cout << i << '\n';
}
int main() {
boost::signal<void(int)> sig;
sig.connect(f);
std::string s="123";
auto first=s.cbegin(), last=s.cend();
boost::spirit::qi::parse(
first, last,
(
boost::spirit::qi::int_
[
boost::phoenix::bind(sig, boost::spirit::qi::_1)
]
)
);
}
This doesn't compile, spitting out a wall of errors.
Note that if I replace the phoenix bind line with
boost::phoenix::bind(&f, boost::spirit::qi::_1)
it works as expected (however due to the larger design of the program this isn't possible).
Thanks in advance.
As noted by Igor R. in the comments, your original error was due to the fact that phoenix::bind copies its arguments by default and boost::signals are non-copyable. When you use phoenix::ref to solve that, another error emerges, this one caused by Boost.Phoenix v2's inability to find the returned type. This can also be easily solved by defining BOOST_SPIRIT_USE_PHOENIX_V3.
#include <boost/signals.hpp>
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <iostream>
void f(int i) {
std::cout << i << '\n';
}
int main() {
boost::signal<void(int)> sig;
sig.connect(f);
std::string s="123";
auto first=s.cbegin(), last=s.cend();
boost::spirit::qi::parse(
first, last,
(
boost::spirit::qi::int_
[
boost::phoenix::bind(boost::phoenix::ref(sig), boost::spirit::qi::_1)
]
)
);
}