Opened 7 years ago

Closed 7 years ago

#11631 closed Bugs (fixed)

boost chrono io v2 does not let you support custom clocks

Reported by: Sébastien Barthélémy <barthelemy@…> Owned by: viboes
Milestone: Boost 1.60.0 Component: chrono
Version: Boost 1.58.0 Severity: Problem
Keywords: Cc:

Description

v1 lets you specialize struct clock_string in order to add support for a custom clock.

I could not find a way to do the equivalent with v2. If confirmed, that would also mean that boost chrono io canot support std::chrono clocks.

Attached is a minimalistic example showing a custom clock with chrono io v1 support. The code does not compile under v2.

Compilation result with boost 1.58

$ make clean && make test
rm -f src/*.o src/chrono_io
clang++ -std=c++11 -c -g -fPIC -Iinclude -I/usr/include -o src/chrono_io.o src/chrono_io.cc
clang++ -std=c++11 -rdynamic -Lsrc -o src/chrono_io src/chrono_io.o -lboost_chrono -lboost_system -L/usr/lib/x86_64-linux-gnu
LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu ./src/chrono_io
1402372272646902866 nanoseconds since year 2k

idem with #define BOOST_CHRONO_DONT_PROVIDES_DEPRECATED_IO_SINCE_V2_0_0

$ make clean && make test
rm -f src/*.o src/chrono_io
clang++ -std=c++11 -c -g -fPIC -Iinclude -I/usr/include -o src/chrono_io.o src/chrono_io.cc
In file included from src/chrono_io.cc:4:
In file included from /usr/include/boost/chrono/chrono_io.hpp:26:
In file included from /usr/include/boost/chrono/io/time_point_io.hpp:22:
In file included from /usr/include/boost/chrono/io/time_point_put.hpp:15:
/usr/include/boost/chrono/io/time_point_units.hpp:77:16: error: no matching member function for call to 'do_get_epoch'
        return do_get_epoch(Clock());
               ^~~~~~~~~~~~
/usr/include/boost/chrono/io/time_point_put.hpp:236:42: note: in instantiation of function template specialization
      'boost::chrono::time_point_units<char>::get_epoch<MyMillenniumClock>' requested here
        string_type str = facet.template get_epoch<Clock>();
                                         ^
/usr/include/boost/chrono/io/time_point_put.hpp:134:19: note: in instantiation of function template specialization
      'boost::chrono::time_point_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put_epoch<MyMillenniumClock>' requested
      here
              s = put_epoch<Clock> (units_facet, s, ios);
                  ^
/usr/include/boost/chrono/io/time_point_put.hpp:170:18: note: in instantiation of function template specialization
      'boost::chrono::time_point_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put<MyMillenniumClock,
      boost::chrono::duration<long, boost::ratio<1, 1000000000> > >' requested here
          return put(facet, i, ios, fill, tp, str.data(), str.data() + str.size());
                 ^
/usr/include/boost/chrono/io/time_point_io.hpp:662:44: note: in instantiation of function template specialization
      'boost::chrono::time_point_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::put<MyMillenniumClock,
      boost::chrono::duration<long, boost::ratio<1, 1000000000> > >' requested here
              if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
                                           ^
src/chrono_io.cc:45:15: note: in instantiation of function template specialization 'boost::chrono::operator<<<char, std::char_traits<char>,
      MyMillenniumClock, boost::chrono::duration<long, boost::ratio<1, 1000000000> > >' requested here
    std::cout << MyMillenniumClock::now() << std::endl;
              ^
/usr/include/boost/chrono/io/time_point_units.hpp:92:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::system_clock' for 1st argument
      virtual string_type do_get_epoch(system_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:99:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::steady_clock' for 1st argument
      virtual string_type do_get_epoch(steady_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:107:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::process_real_cpu_clock' for 1st argument
      virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:114:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::process_user_cpu_clock' for 1st argument
      virtual string_type do_get_epoch(process_user_cpu_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:120:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::process_system_cpu_clock' for 1st argument
      virtual string_type do_get_epoch(process_system_cpu_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:126:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::process_cpu_clock' for 1st argument
      virtual string_type do_get_epoch(process_cpu_clock) const=0;
                          ^
/usr/include/boost/chrono/io/time_point_units.hpp:135:27: note: candidate function not viable: no known conversion from 'MyMillenniumClock' to
      'boost::chrono::thread_clock' for 1st argument
      virtual string_type do_get_epoch(thread_clock) const=0;
                          ^
1 error generated.
Makefile:7: recipe for target 'src/chrono_io.o' failed
make: *** [src/chrono_io.o] Error 1

Attachments (1)

chrono_io_custom.tgz (1.0 KB ) - added by Sébastien Barthélémy <barthelemy@…> 7 years ago.

Download all attachments as: .zip

Change History (4)

by Sébastien Barthélémy <barthelemy@…>, 7 years ago

Attachment: chrono_io_custom.tgz added

comment:1 by viboes, 7 years ago

Status: newassigned

My bad. maybe the documentation is not explicit enough that this is not supported.

The reference states the possible customization points

  protected:
    virtual ~time_point_units();
    virtual string_type do_get_epoch(system_clock) const=0;
    virtual string_type do_get_epoch(steady_clock) const=0;

#if defined(BOOST_CHRONO_HAS_PROCESS_CLOCKS)
    virtual string_type do_get_epoch(process_real_cpu_clock) const=0;
    virtual string_type do_get_epoch(process_user_cpu_clock) const=0;
    virtual string_type do_get_epoch(process_system_cpu_clock) const=0;
    virtual string_type do_get_epoch(process_cpu_clock) const=0;
#endif
#if defined(BOOST_CHRONO_HAS_THREAD_CLOCK)
    virtual string_type do_get_epoch(thread_clock) const=0;
#endif}}}

I would need to type erase the clock in someway, but I don't know how the user could identify its clock.  

comment:2 by viboes, 7 years ago

Milestone: To Be DeterminedBoost 1.60.0

I think that I have found a way the user can customize the Clock string. I don't know however how it can customize it depending on a specific locale.

The trick is to use an indirection

      template <typename Clock>
      string_type get_epoch() const
      {
        return get_epoch_custom<CharT>(Clock(), *this);
      }

where get_epoch_custom just forwards again to the facet.

    template <typename CharT, typename Clock, typename TPUFacet>
    std::basic_string<CharT> get_epoch_custom(Clock, TPUFacet& f)
    {
      return f.do_get_epoch(Clock());
    }

The user can specialize its onw Clock by overloading this customization function.

template <typename CharT, typename TPUFacet>
std::basic_string<CharT> get_epoch_custom(MyMillenniumClock, TPUFacet&)
{
  return boost::chrono::clock_string<MyMillenniumClock,CharT>::since();
}

Committed in master branch https://github.com/boostorg/chrono/commit/533851116fa2c3870e05d878a9cc9c82c4b93fa1

Note: See TracTickets for help on using tickets.