|
21 | 21 | #include <cmath>
|
22 | 22 | #include <limits>
|
23 | 23 | #include <vector>
|
| 24 | +#include <deque> |
| 25 | +#include <list> |
| 26 | +#include <stack> |
| 27 | +#include <queue> |
24 | 28 | #include <memory>
|
25 | 29 | #include <unordered_map>
|
26 | 30 | #include <type_traits>
|
@@ -357,6 +361,50 @@ namespace po {
|
357 | 361 | template< value_type type >
|
358 | 362 | using vt2type = typename detail::vt2type_impl< type >::type;
|
359 | 363 |
|
| 364 | + namespace detail { |
| 365 | + template< |
| 366 | + typename T, |
| 367 | + bool is_integral = std::is_integral< T >::value, |
| 368 | + bool is_floating_point = std::is_floating_point< T >::value, |
| 369 | + bool is_signed = std::numeric_limits< T >::is_signed |
| 370 | + > |
| 371 | + struct type2vt_impl { |
| 372 | + // Not using false because then it would trigger without instatiation. |
| 373 | + // Instead, use an expression that always evaluates to false but depends on T. |
| 374 | + static_assert( !std::is_same< T, T >::value, "type2vt: unsupported type" ); |
| 375 | + static constexpr value_type value = void_; |
| 376 | + }; |
| 377 | + template<> |
| 378 | + struct type2vt_impl< void, false, false, false > { |
| 379 | + static constexpr value_type value = void_; |
| 380 | + }; |
| 381 | + template<> |
| 382 | + struct type2vt_impl< std::string, false, false, false > { |
| 383 | + static constexpr value_type value = string; |
| 384 | + }; |
| 385 | + template< typename T > |
| 386 | + struct type2vt_impl< T, true, false, true > { |
| 387 | + static constexpr std::size_t T_bits = sizeof( T ) * std::numeric_limits< unsigned char >::digits; |
| 388 | + static_assert( T_bits == 32 || T_bits == 64, "type2vt: only 32 or 64 bit wide signed integral types supported" ); |
| 389 | + static constexpr value_type value = ( T_bits == 32 ) ? i32 : i64; |
| 390 | + }; |
| 391 | + template< typename T > |
| 392 | + struct type2vt_impl< T, true, false, false > { |
| 393 | + static constexpr std::size_t T_bits = sizeof( T ) * std::numeric_limits< unsigned char >::digits; |
| 394 | + static_assert( T_bits == 32 || T_bits == 64, "type2vt: only 32 or 64 bit wide unsigned integral types supported" ); |
| 395 | + static constexpr value_type value = ( T_bits == 32 ) ? u32 : u64; |
| 396 | + }; |
| 397 | + template< typename T > |
| 398 | + struct type2vt_impl< T, false, true, true > { |
| 399 | + static constexpr std::size_t T_bits = sizeof( T ) * std::numeric_limits< unsigned char >::digits; |
| 400 | + static_assert( T_bits == 32 || T_bits == 64, "type2vt: only 32 or 64 bit wide floating point types supported" ); |
| 401 | + static constexpr value_type value = ( T_bits == 32 ) ? f32 : f64; |
| 402 | + }; |
| 403 | + } |
| 404 | + template< typename T > |
| 405 | + struct type2vt : detail::type2vt_impl< typename std::remove_cv< T >::type > { |
| 406 | + }; |
| 407 | + |
360 | 408 | template< typename T >
|
361 | 409 | T pow( T base, unsigned exp ) {
|
362 | 410 | if( exp == 0 )
|
@@ -1604,6 +1652,47 @@ namespace po {
|
1604 | 1652 | return *this;
|
1605 | 1653 | }
|
1606 | 1654 |
|
| 1655 | + template< typename T > |
| 1656 | + option& bind_container( T& target ) { |
| 1657 | + using value_type = typename T::value_type; |
| 1658 | + type( type2vt< value_type >::value ); |
| 1659 | + multi(); |
| 1660 | + callback( [ &target ]( value_type const& x ){ target.push_back( x ); } ); |
| 1661 | + return *this; |
| 1662 | + } |
| 1663 | + |
| 1664 | + template< typename T > |
| 1665 | + option& bind( T& target ) { |
| 1666 | + type( type2vt< T >::value ); |
| 1667 | + single(); |
| 1668 | + callback( [ &target ]( T const& x ){ target = x; } ); |
| 1669 | + return *this; |
| 1670 | + } |
| 1671 | + template< typename T > |
| 1672 | + option& bind( std::vector< T >& target ) { |
| 1673 | + return bind_container( target ); |
| 1674 | + } |
| 1675 | + template< typename T > |
| 1676 | + option& bind( std::deque< T >& target ) { |
| 1677 | + return bind_container( target ); |
| 1678 | + } |
| 1679 | + template< typename T > |
| 1680 | + option& bind( std::list< T >& target ) { |
| 1681 | + return bind_container( target ); |
| 1682 | + } |
| 1683 | + template< typename T > |
| 1684 | + option& bind( std::stack< T >& target ) { |
| 1685 | + return bind_container( target ); |
| 1686 | + } |
| 1687 | + template< typename T > |
| 1688 | + option& bind( std::queue< T >& target ) { |
| 1689 | + return bind_container( target ); |
| 1690 | + } |
| 1691 | + template< typename T > |
| 1692 | + option& bind( std::priority_queue< T >& target ) { |
| 1693 | + return bind_container( target ); |
| 1694 | + } |
| 1695 | + |
1607 | 1696 | private:
|
1608 | 1697 | std::unique_ptr< value_vector_base > make_vector() const {
|
1609 | 1698 | const bool arg1 = ( get_type() == void_ );
|
|
0 commit comments