the Compartmented Robust Posix C++ Unit Test system

Chapter 7. Controlling data display format

When crpcut needs to display the value of an object, for example in a violation report due to a failed ASSERT_TRUE(expr), it defaults to using std::ostream& operator<<(std::ostream&const T&) if it is defined for the type, or a hex-dump otherwise.

Should you want to display your data types in a different format, you can specialize the function template void crpcut::show_value<>(std::ostream&const T&) to display the value in any format you prefer.

Example:

     
     #include <crpcut.hpp>
     
     class unstreamable {
     public:
       unstreamable(int i) : i_(i) {}
     private:
       int i_;
     };
     
     class unstreamable_special {
     public:
       unstreamable_special(int i) : i_(i) {}
     private:
       int i_;
       friend void crpcut::show_value<>(std::ostream&, const unstreamable_special&);
     };
     
     class streamable_special {
     public:
       streamable_special(int i) : i_(i) {}
     private:
       int i_;
       friend std::ostream &operator<<(std::ostream &os,
                                       const streamable_special &obj)
       {
         return os << "stream(" << obj.i_ << ")";
       }
       friend void crpcut::show_value<>(std::ostream &, const streamable_special&);
     };
     
     namespace crpcut { // for specializations of crpcut::show_value<>()
       template <>
       void show_value(std::ostream &os, const unstreamable_special &obj)
       {
         os << "special(" << obj.i_ << ")";
       }
       template <>
       void show_value(std::ostream &os, const streamable_special &obj)
       {
         os << "streamable_special(" << obj.i_ << ")";
       }
     }
     
     TEST(show_it_all)
     {
       int i(0);
       unstreamable u(1);
       unstreamable_special us(2);
       streamable_special ss(3);
     
       INFO << "i=" << i;   // default stream insertion
       INFO << "u=" << u;   // hex dump
       INFO << "us=" << us; // specialized
       INFO << "ss=" << ss; // specialized
       std::ostringstream os;
       os << ss;
       INFO << "ss from std::ostream = " << os.str(); // default stream insertion
     }
     
     int main(int argc, char *argv[])
     {
       return crpcut::run(argc, argv);
     }

The result from running the example program is:


     PASSED!: show_it_all
     info---------------------------------------------------------------------------
     samples/show-value-example.cpp:78
     i=0
     -------------------------------------------------------------------------------
     info---------------------------------------------------------------------------
     samples/show-value-example.cpp:79
     u=4-byte object <0100 0000>
     -------------------------------------------------------------------------------
     info---------------------------------------------------------------------------
     samples/show-value-example.cpp:80
     us=special(2)
     -------------------------------------------------------------------------------
     info---------------------------------------------------------------------------
     samples/show-value-example.cpp:81
     ss=streamable_special(3)
     -------------------------------------------------------------------------------
     info---------------------------------------------------------------------------
     samples/show-value-example.cpp:84
     ss from std::ostream = stream(3)
     ===============================================================================
     1 test cases selected
     
                    Sum   Critical   Non-critical
     PASSED   :       1          1              0

As can be seen, the specialized crpcut::show_value<T>() is preferred when both it and the normal stream insertion operator are available.