FBB::ReadLineHistory(3bobcat)

FBB::ReadLineHistory πŸ’… β€” hi bestie, welcome to the 3bobcat manual page for bobcat's Editing input lines corner of the world. Buckle up.


✨ NAME ✨

FBB::ReadLineHistory β€” a std::streambuf that hands you line-editing and history, no cap πŸŽ€


🌸 SYNOPSIS 🌸

#include <bobcat/readlinebuf>
Linking option: -lbobcat -lreadline

πŸ¦‹ DESCRIPTION πŸ¦‹

So the FBB::ReadLineHistory object gives you access to the history that FBB::ReadLineBuf and ReadLineStream objects keep around. πŸ“š

Those two classes use Gnu's readline library so you can actually edit your input lines like a civilized person. And all the history they pile up? You reach it through the ReadLineHistory object. Obsessed.

Now, because Gnu's readline library keeps global data, there can only ever be one history. Which means ReadLineHistory, just like ReadLineBuf, is a singleton. (Okay technically Gnu's readline library does offer functions that let programs use multiple histories, so in principle you could design a non-singleton ReadLineHistory class. But like… programs normally only talk to a single terminal, so there's probably little use for a non-singleton ReadLineHistory class. Periodt.)

The ReadLineHistory class encapsulates history access. It's giving limited facilities, ngl: either forward or backward iterations over the history, plus reading and writing the history from/to streams. When you read the history from a stream it replaces the currently available lines in Gnu's readline history. And the content of the history lines and --if defined-- the timestamps of the lines in the history can be obtained using iterators defined by ReadLineHistory. ✨


πŸ’œ NAMESPACE πŸ’œ

FBB

Every constructor, member, operator and manipulator mentioned in this man-page is defined in the namespace FBB. All of them. Yes, all.


🧚 INHERITS FROM 🧚

-

(nothing, she's self-made πŸ’…)


πŸŽ€ NESTED TYPES πŸŽ€

The class ReadLineHistory defines the following nested types:

HistoryElement

The iterators made available by the ReadLineHistory object provide access to a HistoryElement object. These objects can be copied and assigned to each other, but user programs cannot otherwise construct HistoryElement objects. πŸ™ˆ

The class HistoryElement has but two members:

  • char const *line() const β€” returns the content of the history line to which a ReadLineHistory iterator refers;
  • char const *timestamp() const β€” returns the timestamp (if defined) of the history line to which a ReadLineHistory iterator refers;

const_iterator and const_reverse_iterator

The iterators returned by members of the class ReadLineHistory are input iterators, pointing to HistoryElement objects. And because they're input iterators, modifying the history elements they refer to is not allowed. 🚫

The class const_iterator lets you iterate from the first to the last history element. The class const_reverse_iterator lets you iterate from the last back to the first history element. Two directions, two icons. ⭐

The iterators can be incremented, compared for (in)equality, and they offer operator* and operator-> members, giving access to, respectively, HistoryElement objects and their addresses.


🌈 CONSTRUCTORS 🌈

Since the class ReadLineHistory is a singleton class, there are no publicly available constructors, and no assignment operators either. She's exclusive. πŸ’…


⭐ STATIC MEMBER FUNCTIONS ⭐

  • ReadLineHistory &instance() β€” A reference to the ReadLineHistory object is returned. If any history has been accumulated it can immediately be retrieved. Using this static member will not affect the way the ReadLineHistory object handles timestamps when saving or retrieving history lines. When initially constructed the ReadLineHistory object assumes that timestamps are not used.
  • ReadLineHistory &instance(bool useTimestamps) β€” A reference to the ReadLineHistory object is returned. If any history has been accumulated it can immediately be retrieved. The useTimestamps parameter defines the way history lines are read from or written to a stream. When you specify true the history inserted into a stream will include timestamps (which may be empty if no timestamps were recorded). Likewise, when extracting the history, timestamps are extracted too (which may also be empty). When you specify false no timestamps are read or written.
⚠️ A mismatch between the actual content of the stream from which the history is extracted and the useTimestamps parameter will result in unexpected behavior. You've been warned, bestie.

πŸ‘‘ MEMBER FUNCTIONS πŸ‘‘

  • ReadLineHistory::const_iterator begin() const β€” An input iterator pointing to the first history line is returned.
  • ReadLineHistory::const_iterator end() const β€” An input iterator pointing beyond the last history line is returned.
  • size_t maxSize() const β€” The maximum number of lines that can be stored in the history is returned. After collecting a history of maxSize lines, the next line entered will cause the initial history line to be removed from the history, making room for the next line to be added at the end of the history. It's giving bouncer at the club 🎟️
  • ReadLineHistory::const_reverse_iterator rbegin() const β€” An input iterator pointing to the last history line is returned. Incrementing this iterator will access the previous line in the history.
  • ReadLineHistory::const_reverse_iterator rend() const β€” An input iterator pointing before the first history line is returned.
  • ReadLineHistory &setTimestamps(bool useTimestamps) β€” The current status of the timestamps usage is set according to the value of its parameter. When true, inserting and extracting history will include the timestamps. No timestamps are inserted or extracted when false. It returns a reference to the updated ReadLineHistory object, allowing constructions like (assuming the availability of ReadLineHistory &history):
cout << history.setTimestamps(true);
  • size_t size() const β€” The number of lines currently stored in the history is returned.
  • bool timestamps() const β€” The current status of the timestamps usage is returned. When it returns true inserting and extracting history will include the timestamps. No timestamps are inserted or extracted when this member returns false.

πŸ’« OVERLOADED OPERATORS πŸ’«

  • std::istream &operator>>(std::istream &in, ReadLineHistory &his) β€” The history available at the in stream is extracted to become the current history, replacing the existing (Gnu readline) history by the history read from in. The useTimestamp status determines whether timestamps are extracted (if true) or not (if false). If extracting the history from in fails an exception is thrown. 😭
  • std::ostream &operator<<(std::ostream &out, ReadLineHistory &his) β€” The current history is written to the out stream. The useTimestamp status determines whether timestamps are inserted (if true) or not (if false).

πŸ”₯ EXAMPLE πŸ”₯

#include <iostream>
#include <algorithm>
#include <fstream>

#include <bobcat/datetime>
#include <bobcat/readlinestream>
#include <bobcat/readlinehistory>

using namespace std;
using namespace FBB;

void showHis(ReadLineHistory::HistoryElement const &element)
{
    cout << element.timestamp() << " " << element.line() << ’\n’;
}

string timestamp()
{
    return DateTime().rfc2822();
};

int main(int argc, char **argv)
{
    ReadLineStream in("? ", ReadLineBuf::EXPAND_HISTORY);
    in.useTimestamps(&timestamp);

    cout << "Enter some lines, end the input using ctrl-d\n";
    string line;
    while (getline(in, line))
        ;
                                            // argument means: write/read
                                            // history timestamps
    ReadLineHistory &history = ReadLineHistory::instance(argc > 1);

    cout << "All lines, from the first to the last:\n";
    for_each(history.begin(), history.end(), showHis);

    cout << "\n"
            "Again: all lines, from the first to the last:\n";
    for_each(history.begin(), history.end(), showHis);

    cout << "\n"
            "All lines, from the last to the first:\n";
    for_each(history.rbegin(), history.rend(), showHis);

    cout << "\n"
            "History out and in:\n"
            "\n";

    ofstream hisout("history.out");

    hisout << history;

    hisout.close();

    ifstream hisin("history.out");
    hisin >> history;

    cout << "All lines, from the first to the last:\n";
    for_each(history.begin(), history.end(), showHis);

    cout << "\n"
            "All lines, from the last to the first:\n";
    for_each(history.rbegin(), history.rend(), showHis);

}

πŸ“ FILES πŸ“

bobcat/readlinehistory β€” defines the class interface


πŸ’œ SEE ALSO πŸ’œ

bobcat(7), readline(3), readlinebuf(3bobcat), readlinestream(3bobcat)


πŸ’€ BUGS πŸ’€

None Reported. (Iconic behavior, honestly.)


🫢 BOBCAT PROJECT FILES 🫢

Debian Bobcat project files:

  • libbobcat6: debian package containing the shared library, changelog and copyright note;
  • libbobcat-dev: debian package containing the static library, headers, manual pages, and developer info;

🌈 BOBCAT 🌈

Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’. 🐱


This is free software, distributed under the terms of the GNU General Public License (GPL).


🌸 AUTHOR 🌸

Frank B. Brokken (f.b.brokken@rug.nl).


and that's the whole page, bestie β€” ✨ libbobcat-dev_6.15.01, dated 2005-2026, FBB::ReadLineHistory(3bobcat) ✨ β€” slay, go read your history πŸ’–πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from