Skip to content

Instantly share code, notes, and snippets.

@xtozero
Last active April 2, 2017 07:08
Show Gist options
  • Save xtozero/8ead227402d9272da6b055863c96f151 to your computer and use it in GitHub Desktop.
Save xtozero/8ead227402d9272da6b055863c96f151 to your computer and use it in GitHub Desktop.

Revisions

  1. xtozero revised this gist Apr 2, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions TypeChecker.cpp
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,9 @@ template <typename T, typename U, typename... R>
    class TypeChecker : public TypeChecker<T, R...>
    {
    public:
    using TypeChecker<T, R...>::TypeChecker;
    using TypeChecker<T, R...>::operator=;

    template <typename ANY>
    TypeChecker( ANY&& arg ) : TypeChecker<T, R...>{ arg }
    {
    @@ -24,9 +27,6 @@ class TypeChecker : public TypeChecker<T, R...>
    TypeChecker<T, R...>::operator=( std::forward<ANY>( arg ) );
    return *this;
    }

    using TypeChecker<T, R...>::TypeChecker;
    using TypeChecker<T, R...>::operator=;
    };

    template <typename T, typename U>
  2. xtozero renamed this gist Apr 2, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. xtozero revised this gist Apr 2, 2017. 1 changed file with 26 additions and 26 deletions.
    52 changes: 26 additions & 26 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -7,19 +7,19 @@ class TypeChecker : public TypeChecker<T, R...>
    {
    public:
    template <typename ANY>
    TypeChecker( ANY&& arg ) : TypeChecker<T, R...>{ arg }
    TypeChecker( ANY&& arg ) : TypeChecker<T, R...>{ arg }
    {
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    }

    template <typename ANY>
    TypeChecker& operator=( ANY&& arg )
    {
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    TypeChecker& operator=( ANY&& arg )
    {
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );

    TypeChecker<T, R...>::operator=( std::forward<ANY>( arg ) );
    return *this;
    @@ -37,33 +37,33 @@ public:
    using T::operator=;

    template <typename ANY>
    TypeChecker( ANY&& arg ) : T{ std::forward<ANY>( arg ) }
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    TypeChecker( ANY&& arg ) : T{ std::forward<ANY>( arg ) }
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    }

    template <typename ANY>
    TypeChecker& operator=( ANY&& arg )
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );

    T::operator=( std::forward<ANY>( arg ) );
    return *this;
    TypeChecker& operator=( ANY&& arg )
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );

    T::operator=( std::forward<ANY>( arg ) );
    return *this;
    }

    protected:
    template <typename ANY>
    void CheckType( ANY&& arg, std::true_type ) { static_assert( false, "Invalid Data Type used" ); }
    void CheckType( ANY&& arg, std::true_type ) { static_assert(false, "Invalid Data Type used"); }

    template <typename ANY>
    void CheckType( ANY&& , std::false_type ) {}
    void CheckType( ANY&&, std::false_type ) {}
    };

    using TCString = TypeChecker<std::string, bool> ;
    using TCString = TypeChecker<std::string, bool>;
    void UseTypeCheckString( const TCString& arg )
    {
    std::cout << arg << std::endl;
    @@ -86,7 +86,7 @@ int main()
    {
    char c_str[] = "c-style string";
    UseTypeCheckString( c_str ); // ok

    std::string str = "string variable";
    UseTypeCheckString( str ); // ok

  4. xtozero revised this gist Apr 2, 2017. No changes.
  5. xtozero created this gist Apr 2, 2017.
    108 changes: 108 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,108 @@
    #include <iostream>
    #include <utility>
    #include <string>

    template <typename T, typename U, typename... R>
    class TypeChecker : public TypeChecker<T, R...>
    {
    public:
    template <typename ANY>
    TypeChecker( ANY&& arg ) : TypeChecker<T, R...>{ arg }
    {
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    }

    template <typename ANY>
    TypeChecker& operator=( ANY&& arg )
    {
    TypeChecker<T, R...>::CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );

    TypeChecker<T, R...>::operator=( std::forward<ANY>( arg ) );
    return *this;
    }

    using TypeChecker<T, R...>::TypeChecker;
    using TypeChecker<T, R...>::operator=;
    };

    template <typename T, typename U>
    class TypeChecker<T, U> : public T
    {
    public:
    using T::T;
    using T::operator=;

    template <typename ANY>
    TypeChecker( ANY&& arg ) : T{ std::forward<ANY>( arg ) }
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );
    }

    template <typename ANY>
    TypeChecker& operator=( ANY&& arg )
    {
    CheckType( std::forward<ANY>( arg ),
    std::is_same<typename std::decay<ANY>::type,
    typename std::decay<U>::type>() );

    T::operator=( std::forward<ANY>( arg ) );
    return *this;
    }

    protected:
    template <typename ANY>
    void CheckType( ANY&& arg, std::true_type ) { static_assert( false, "Invalid Data Type used" ); }

    template <typename ANY>
    void CheckType( ANY&& , std::false_type ) {}
    };

    using TCString = TypeChecker<std::string, bool> ;
    void UseTypeCheckString( const TCString& arg )
    {
    std::cout << arg << std::endl;
    }

    void UnuseTypeCheckString( const std::string& arg )
    {
    std::cout << arg << std::endl;
    }

    class Int
    {
    public:
    Int( ... ) {}
    };

    using TCInt = TypeChecker<Int, bool, long>;

    int main()
    {
    char c_str[] = "c-style string";
    UseTypeCheckString( c_str ); // ok

    std::string str = "string variable";
    UseTypeCheckString( str ); // ok

    const char* const_c_str = "cibst c-style string";
    UseTypeCheckString( const_c_str ); // ok

    const std::string const_str = "const string";
    UseTypeCheckString( const_str ); // ok

    UnuseTypeCheckString( false ); // compile success but runtime error

    UseTypeCheckString( false ); // compile time error

    TCInt a( 'c' ); // ok
    TCInt b( 1 ); // ok
    TCInt c( 3.14 ); // ok
    TCInt d( false ); // compile time error
    TCInt e( 1L ); // compile time error
    }