Elementa v8.0.0
Minimalistic library for any C++ application (C++11 and up)
Loading...
Searching...
No Matches
basics.h
Go to the documentation of this file.
1
3#include "elementa/license.inc"
4#include "elementa/checks.inc"
5
6#ifndef ELEMENTA_BASE_SERIALCHANNELS_BASICS_H
7#define ELEMENTA_BASE_SERIALCHANNELS_BASICS_H
8
9#include <iostream>
10#include <string>
15
16namespace elementa
17{
18
19namespace base
20{
21
157/* ======================================================================
158
159 GENERAL DEFINITIONS
160
161 (since there are classes in here, we do not use \name to group because
162 classes are not affected by \name)
163
164========================================================================= */
165
166
167/* ***************************************************************************
168
169 Types, consts, etc.
170
171*****************************************************************************/
172
174
178using SerChSize = std::streamsize;
179
181using SerChDatum = std::streambuf::int_type;
182
184
186using SerChCharTraits = std::char_traits<char>;
187
189constexpr SerChDatum kSerChEOF = std::streambuf::traits_type::eof();
190
192
195using RootSerCh = std::ios;
196
197
198/* ***************************************************************************
199
200 Base class: OutSerCh
201
202*****************************************************************************/
203
205
247using OutSerCh = std::ostream;
248
249
250/* ***************************************************************************
251
252 Base class: InSerCh
253
254*****************************************************************************/
255
257
334using InSerCh = std::istream;
335
336
337/* ***************************************************************************
338
339 Base class: InOutSerCh
340
341*****************************************************************************/
342
344
356using InOutSerCh = std::iostream;
357
358
359
360/* ======================================================================
361
362 TRAITS MANAGEMENT
363
364========================================================================= */
365
366
367/* ***************************************************************************
368
369 Template classes: is_SerCh, is_InSerCh, is_OutSerCh, is_InOutSerCh
370
371*****************************************************************************/
372
374template <class T>
376{
377 public:
378
379 static constexpr bool value =
380 ( std::is_base_of<InSerCh,T>::value &&
381 std::is_same<typename T::char_type,char>::value
382 );
383};
384
385
387template <class T>
389{
390 public:
391
392 static constexpr bool value =
393 ( ( std::is_base_of<InSerCh,T>::value ||
394 std::is_base_of<InOutSerCh,T>::value ) &&
395 std::is_same<typename T::char_type,char>::value
396 );
397};
398
399
401template <class T>
403{
404 public:
405
406 static constexpr bool value =
407 ( std::is_base_of<OutSerCh,T>::value &&
408 std::is_same<typename T::char_type,char>::value
409 );
410};
411
412
414template <class T>
416{
417 public:
418
419 static constexpr bool value =
420 ( ( std::is_base_of<OutSerCh,T>::value ||
421 std::is_base_of<InOutSerCh,T>::value ) &&
422 std::is_same<typename T::char_type,char>::value
423 );
424};
425
426
428template <class T>
430{
431 public:
432
433 static constexpr bool value =
434 ( std::is_base_of<InOutSerCh,T>::value &&
435 std::is_same<typename T::char_type,char>::value
436 );
437};
438
439
441template <class T>
443{
444 public:
445
446 static constexpr bool value = ( is_InSerCh<T>::value ||
449};
450
451
452
453/* ======================================================================
454
455 STATE MANAGEMENT
456
457========================================================================= */
458
459
460/* ***************************************************************************
461
462 Functions: serch_isgood, serch_iseofbutok, serch_isexhausted,
463 serch_hasreadN, serch_haswrittenN
464
465*****************************************************************************/
466
468
469void serch_isgood(RootSerCh & serchconst,
470 const std::string & place = "",
471 const RTTextWithEnum::Combination & flags
472 = {RTTextWith::kAll_});
473
475
476bool serch_iseofbutok(RootSerCh & serchconst,
477 const std::string & place = "",
478 const RTTextWithEnum::Combination & flags
479 = {RTTextWith::kAll_});
480
482
485 const std::string & place = "",
486 const RTTextWithEnum::Combination & flags
487 = {RTTextWith::kAll_});
488
490void serch_hasreadN(InSerCh & chin, char * dest, SerChSize n,
491 const std::string & place = "",
492 const RTTextWithEnum::Combination & flags
493 = {RTTextWith::kAll_});
494
496void serch_haswrittenN(OutSerCh & chout, const char * org, SerChSize n,
497 const std::string & place = "",
498 const RTTextWithEnum::Combination & flags
499 = {RTTextWith::kAll_});
500
501
502/* ***************************************************************************
503
504 Function: serch_st_to_string
505
506*****************************************************************************/
507
509
512std::string serch_st_to_string(std::ios_base::iostate st) noexcept;
513
515inline std::string serch_st_to_string(RootSerCh & ch) noexcept
516 { return(serch_st_to_string(ch.rdstate())); }
517
519std::ios_base::iostate serch_copy_st(RootSerCh & chorg, RootSerCh & chdest);
520
521
522
523/* ======================================================================
524
525 ERROR MANAGEMENT
526
527========================================================================= */
528
529
530/* ***************************************************************************
531
532 Classes: SerChError, SerChErr_Exhausted
533
534*****************************************************************************/
535
537class SerChError: public Exc
538{
539 public:
540
541 SerChError(const std::string & explanation):
542 Exc{std::string{"Serial channel error: "} +
544 {}
545
547};
548
549
552{
553 public:
554
555 SerChErr_Exhausted(const std::string & explanation):
556 SerChError{concatWithMiddle("Channel exhausted",
558 {}
559
561};
562
563
566{
567 public:
568
569 SerChErr_FewData(const std::string & explanation):
571 "Channel provided less data than expected",
573 {}
574
576};
577
580{
581 public:
582
583 SerChErr_TooManyData(const std::string & explanation):
585 "Too many data in channel",
587 {}
588
590};
591
592
595{
596 public:
597
598 SerChErr_State(const std::string & explanation):
599 SerChError{concatWithMiddle("Not good channel state",
601 {}
602
604};
605
606
609{
610 public:
611
612 SerChErr_Unopened(const std::string & explanation):
613 SerChError{concatWithMiddle("Unopened channel",
615 {}
616
618};
619
620
623{
624 public:
625
626 SerChErr_Loc(const std::string & explanation):
627 SerChError{concatWithMiddle("Location error",explanation)}
628 {}
629
631};
632
633
636{
637 public:
638
639 SerChErr_Cont(const std::string & explanation):
640 SerChError{concatWithMiddle("Container channel error",
642 {}
643
645};
646
647
648
649/* ======================================================================
650
651 ADDITIONAL CHANNEL FUNCTIONALITY
652
653========================================================================= */
654
655
656/* ***************************************************************************
657
658 Function template: serch_transfer
659
660*****************************************************************************/
661
663
677template <class SCOrg, class SCDest>
678SerChSize serch_transfer(SCOrg & chin, SCDest & chout, SerChSize count = 0)
679{
680 static_assert(is_In_InOut_SerCh<SCOrg>::value &&
682 "Cannot instantiate general serch_transfer with non-channel");
683
685
686 ELE_CODE_TRACE({},"general case of serch_transfer (chin state={" <<
687 serch_st_to_string(chin) <<
688 "}, chout state={" <<
689 serch_st_to_string(chout) <<
690 "}, count = " << count);
691 SerChSize res = 0;
692 if ( (chin.good()) && (chout.good()) )
693 {
694 ELE_CODE_UNTRACE({},"Both channels good for transfer " << count);
695 char c;
696 bool finish{false};
697 while (!finish)
698 {
699 c = chin.get();
700 ELE_CODE_UNTRACE({},"Transferring '" << c << "' (" << to_number(c) <<
701 ")");
702 if (!chin.good())
703 {
704 ELE_CODE_UNTRACE({},"chin channel not good. res = " << res);
705 break;
706 }
707 chout.put(c);
708 if (!chout.good())
709 {
710 ELE_CODE_UNTRACE({},"chout channel not good. res = " << res);
711 break;
712 }
713 ++res;
714 finish = (count == 0 ? false : (res >= count));
715 }
716 ELE_CODE_UNTRACE({},"Transferred " << res);
717 }
718 return(res);
719}
720
721
723
737template <class SCOrg, class SCDest>
739 SCDest && chout,
740 SerChSize count = 1)
741{
743
744 ELE_CODE_TRACE({},"rvalue version of serch_transfer - redirecting");
745 return(serch_transfer(chin,chout,count));
746}
747
748
749/* *************************************************************************
750
751 Class: SerChLoc
752
753*****************************************************************************/
754
756
769{
770 public:
771
776 using Ptr = std::shared_ptr<SerChLoc>;
777
785 SerChLoc(void) noexcept { reset(); }
786
788 SerChLoc(const SerChLoc & oth)
789 { copyFrom(oth); }
790
793 { copyFrom(oth); return(*this); }
794
796 SerChLoc(SerChLoc && oth) { moveFrom(oth); }
797
799 SerChLoc & operator=(SerChLoc && oth) { moveFrom(oth); return(*this); }
800
802 virtual ~SerChLoc(void) {}
803
811 SerChSize linear(void) const noexcept { return(lpos_); }
812
820 virtual SerChLoc * clone(void) const
821 { return(new SerChLoc{*this}); }
822
824 virtual void reset(void) noexcept
825 { lpos_ = 0; }
826
828
829 virtual void inc(char c = ' ') { ++lpos_; }
830
832
833 virtual void inc(const char * t, SerChSize n)
834 { if ((t==nullptr)||(n==0)) return;
835 lpos_ += n; }
836
838
840 virtual void dec(char c);
841
843
845 virtual void dec(const char * t, SerChSize n);
846
848 virtual bool operator==(const SerChLoc & o) const
849 { return(lpos_ == o.lpos_); }
850
852 virtual bool operator!=(const SerChLoc & o) const
853 { return(!operator==(o)); }
854
856
857 virtual std::string to_string(bool compact = false) const noexcept;
858
866 protected:
867
868 SerChSize lpos_;
869
870 private:
871
872 void copyFrom(const SerChLoc & oth)
873 { if (this != &oth) lpos_ = oth.lpos_; }
874
875 void moveFrom(SerChLoc & oth)
876 { if (this != &oth) copyFrom(oth); }
877
878};
879
880
881/* *************************************************************************
882
883 Class: SerChLocText
884
885*****************************************************************************/
886
888
898{
899 public:
900
902 SerChLocText(char endofline = '\n') noexcept: eol_{endofline}
903 { reset(); }
904
907 { copyFrom(oth); }
908
911 { copyFrom(oth); return(*this); }
912
915 { moveFrom(oth); }
916
919 { moveFrom(oth); return(*this); }
920
922 virtual ~SerChLocText(void) {}
923
925 SerChSize row(void) const noexcept { return(row_); }
926
928 SerChSize column(void) const noexcept { return(col_); }
929
930 SerChLocText * clone(void) const
931 { return(new SerChLocText{*this}); }
932 void reset(void) noexcept override;
933 void inc(char c) override;
934 void inc(const char * t, SerChSize n) override;
935 void dec(char c) override;
936 void dec(const char * t, SerChSize n) override;
937 bool operator==(const SerChLocText & o)
938 { return((eol_ == o.eol_)&&(row_ == o.row_)&&(col_ == o.col_)); }
939 bool operator!=(const SerChLocText & o)
940 { return(!operator==(o)); }
941 bool operator==(const SerChLoc & o) const override
942 { return(operator==(dynamic_cast<const SerChLocText &>(o))); }
943 bool operator!=(const SerChLoc & o) const override
944 { return(!operator==(o)); }
945 std::string to_string(bool compact = false) const noexcept override;
946
947
948 private:
949
950 using RowInfo = std::vector<std::pair<SerChSize, SerChSize>>;
951
952 char eol_;
953 SerChSize row_,col_;
954 RowInfo row_info_;
955
956 void copyFrom(const SerChLocText & oth);
957 void moveFrom(SerChLocText & oth)
958 { if (this != &oth) copyFrom(oth); }
959
960 std::string rowinfotostring(void) const;
961};
962 // SerCh_basics
964
965
966} // end namespace base
967
968} // end namespace elementa
969
970#endif
971
Any class derived from this base class must be clonable.
Definition: clonable.h:83
#define ELE_CODE_TRACE_OFF
Place this inside local scope (e.g., routine) to deactivate traces there.
Definition: debugging.h:283
#define ELE_CODE_UNTRACE(flags,...)
Macro to use instead of an existing ELE_CODE_TRACE to deactivate that trace.
Definition: debugging.h:437
const char * explanation(void) const noexcept
Return the explanation only. It will live as long as this exception.
Definition: exceptions.h:164
Base class for all errors / exceptions in Elementa. Just derive from it.
Definition: exceptions.h:113
#define ELE_CLASS_EXCOVERRIDE(C)
Shortening macro that must be used inside classes derived from Exc.
Definition: exceptions.h:64
LongestUnsigned to_number(const void *p)
Convert a pointer address to a number.
bool operator!=(const SerChLoc &o) const override
Unequality.
Definition: basics.h:943
bool operator==(const SerChLoc &o) const override
Equality.
Definition: basics.h:941
std::string to_string(bool compact=false) const noexcept override
Convert the location to a string.
void inc(char c) override
Increment the location after reading/writing char C.
virtual void dec(const char *t, SerChSize n)
Decrement the location after un-reading/un-writing a block T of N chars.
SerChLocText & operator=(const SerChLocText &oth)
Copy assignment: the stored value is cleared.
Definition: basics.h:910
virtual void inc(char c=' ')
Increment the location after reading/writing char C.
Definition: basics.h:829
SerChLocText & operator=(SerChLocText &&oth)
Move assignment: the stored value of OTH is moved to this.
Definition: basics.h:918
virtual ~SerChLocText(void)
Destructor.
Definition: basics.h:922
SerChLocText(SerChLocText &&oth)
Move constructor: the stored value of OTH is moved to this.
Definition: basics.h:914
SerChLoc & operator=(SerChLoc &&oth)
Move assignment: the stored value of OTH is moved to this.
Definition: basics.h:799
SerChSize column(void) const noexcept
Get current column.
Definition: basics.h:928
virtual SerChLoc * clone(void) const
Clone the location.
Definition: basics.h:820
void dec(char c) override
Decrement the location after un-reading/un-writing char C.
std::shared_ptr< SerChLoc > Ptr
Safe pointer for polymorphic behaviours.
Definition: basics.h:776
SerChSize linear(void) const noexcept
Get the current location.
Definition: basics.h:811
void inc(const char *t, SerChSize n) override
Increment the location after reading/writing a block T of N chars.
SerChLoc(void) noexcept
Default constructor: establish 0 as the current location in the channel.
Definition: basics.h:785
virtual void inc(const char *t, SerChSize n)
Increment the location after reading/writing a block T of N chars.
Definition: basics.h:833
SerChLoc & operator=(const SerChLoc &oth)
Copy assignment: the stored value is cleared.
Definition: basics.h:792
SerChSize row(void) const noexcept
Get current row.
Definition: basics.h:925
SerChLocText(const SerChLocText &oth)
Copy constructor: the stored value is cleared.
Definition: basics.h:906
void reset(void) noexcept override
Reset the location to the beginning.
virtual void dec(char c)
Decrement the location after un-reading/un-writing char C.
virtual ~SerChLoc(void)
Destructor.
Definition: basics.h:802
virtual std::string to_string(bool compact=false) const noexcept
Convert the location to a string.
virtual bool operator!=(const SerChLoc &o) const
Unequality.
Definition: basics.h:852
virtual bool operator==(const SerChLoc &o) const
Equality.
Definition: basics.h:848
virtual void reset(void) noexcept
Reset the location to the beginning.
Definition: basics.h:824
SerChLoc(SerChLoc &&oth)
Move constructor: the stored value of OTH is moved to this.
Definition: basics.h:796
SerChLocText(char endofline='\n') noexcept
Default constructor: location pointing to the 1st character of the text.
Definition: basics.h:902
SerChLoc(const SerChLoc &oth)
Copy constructor: the stored value is cleared.
Definition: basics.h:788
void dec(const char *t, SerChSize n) override
Decrement the location after un-reading/un-writing a block T of N chars.
SerChLocText * clone(void) const
Clone the location.
Definition: basics.h:930
Errors related to container-based channels.
Definition: basics.h:636
Error to throw when the channel is exhausted but it should not be.
Definition: basics.h:552
Error to throw when the channel provides less data than it should on read()
Definition: basics.h:566
Errors related to locations on channels.
Definition: basics.h:623
Errors thrown by serch_isgood and other functions.
Definition: basics.h:595
Error to throw when the channel does not admit too many data.
Definition: basics.h:580
Errors thrown by channels that must be opened.
Definition: basics.h:609
Base class for exceptions associated to some serial channel operation.
Definition: basics.h:538
Location in a channel, at least in linear form, either at reading or writing.
Definition: basics.h:769
A location into a text channel consisting of a row and a column.
Definition: basics.h:898
With this template you can check whether T is an input or inout channel.
Definition: basics.h:389
With this template you can check whether T is an in + out serial channel.
Definition: basics.h:430
With this template you can check whether T is an input serial channel.
Definition: basics.h:376
With this template you can check whether T is an output or inout channel.
Definition: basics.h:416
With this template you can check whether T is an output serial channel.
Definition: basics.h:403
With this template you can check whether T is any kind of serial channel.
Definition: basics.h:443
std::istream InSerCh
"Base class" that represents any input serial channel in Elementa.
Definition: basics.h:334
std::streambuf::int_type SerChDatum
Type that can hold either a char or eof.
Definition: basics.h:181
std::ios RootSerCh
Class that is at the root of any serial channel in Elementa.
Definition: basics.h:195
std::iostream InOutSerCh
"Base class" that represents any input + output serial channel in Elementa.
Definition: basics.h:356
bool serch_isexhausted(InSerCh &serch, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Return TRUE if it is eof or exhausted; then throw if the channel is bad/fail.
std::streamsize SerChSize
Type of the size of any channel.
Definition: basics.h:178
std::ostream OutSerCh
"Base class" that represents any output serial channel in Elementa.
Definition: basics.h:247
bool serch_iseofbutok(RootSerCh &serchconst, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Return TRUE if the channel is eof() (maybe bad/fail); throw if !eof nor good.
SerChSize serch_transfer(SCOrg &chin, SCDest &chout, SerChSize count=0)
Write COUNT items read from channel CHIN into channel CHOUT.
Definition: basics.h:678
std::ios_base::iostate serch_copy_st(RootSerCh &chorg, RootSerCh &chdest)
Copy the state of CHORG into DEST, returning that state.
constexpr SerChDatum kSerChEOF
Const that holds the eof value.
Definition: basics.h:189
void serch_hasreadN(InSerCh &chin, char *dest, SerChSize n, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Make sure that N chars are read from CHIN; throws if any error.
std::char_traits< char > SerChCharTraits
To have access to the methods of char_traits corresponding to these channs.
Definition: basics.h:186
void serch_isgood(RootSerCh &serchconst, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Throw an exception if the channel is not good; do nothing otherwise.
std::string serch_st_to_string(std::ios_base::iostate st) noexcept
Converts an io state into a string.
void serch_haswrittenN(OutSerCh &chout, const char *org, SerChSize n, const std::string &place="", const RTTextWithEnum::Combination &flags={RTTextWith::kAll_})
Make sure that N chars are written to CHOUT; throws if any error.
std::string concatWithMiddle(const std::string &s1, const std::string &s2, const std::string &m=". ")
Concatenate two strings putting a middle one only if the second is not empty.