#include <iostream>

#include <vector>

#include <string>


#define CSTR

#define DSTR


using   int_pair = std::pair< int, int >;

//----------------------------------------------------------------------------------------


struct                          POINT3D

{

    float   x, y, z;


    CSTR                        POINT3D() : x( 0 ), y( 0 ), z( 0 ) {}

    CSTR                        POINT3D( float x, float y, float z )

        : x( x ), y( y ), z( z ) {}


    auto&                       operator=( const POINT3D& rhs )

    {

        x = rhs.x, y = rhs.y, z = rhs.z;

        return  *this;

    }


    friend  std::ostream&       operator<<( std::ostream& os, const POINT3D& p )

    {

        os << " x: " << p.x << std::endl;

        os << " y: " << p.y << std::endl;

        os << " z: " << p.z << std::endl;

        return  os;

    }

};

//----------------------------------------------------------------------------------------


enum    class                   DEVICE_TYPE

{

    sensor,

    motor,

};


class                           DEVICE_MANAGER;


///---------------------------------------------------------------------------------------


class                           DEVICE

{

friend  class                   DEVICE_MANAGER;

private:

    virtual void                refresh() = 0;

    const   DEVICE_TYPE         device_type;


protected:

    std::string                 name;

    virtual void                show() const = 0;


public:

    CSTR                        DEVICE(

        const std::string& name,

        const DEVICE_TYPE device_type )

    :   name( name )

    ,   device_type( device_type )

    {}

};

///---------------------------------------------------------------------------------------


class                           DEVICE_MANAGER

{

private:

    std::vector< DEVICE* >      devices;


public:

    CSTR                        DEVICE_MANAGER()

    {}

    DSTR                       ~DEVICE_MANAGER()

    {

        while( !devices.empty() )

        {

            delete  devices.back();

            devices.pop_back();

        }

    }


    void                        add( const DEVICE* device )

    {

        devices.push_back( (DEVICE*)device );

    }


    void                        refresh() const

    {

        for( auto* device : devices )

            device->refresh();

    }


    void                        show() const

    {

        for( const auto* device : devices )

            device->show();

    }


    template< typename T >

    void                        set( const T& value ) const;

};

//----------------------------------------------------------------------------------------


template< class T >

class                           SENSOR : public DEVICE

{

protected:

    T                           value;


    virtual void                show() const

    {

        std::cout << name << std::endl;

        std::cout << value << std::endl;

    }


public:

    CSTR                        SENSOR( DEVICE_MANAGER* owner, const std::string& name )

    :   DEVICE( name, DEVICE_TYPE::sensor )

    {

        owner->add( ( DEVICE* )this );

    }

    virtual DSTR               ~SENSOR()

    {}


    const   T                   get() const

    {

        return  value;

    }


    void                        set( const T& rvalue )

    {

        value = rvalue;

    }

};

///---------------------------------------------------------------------------------------


template< typename T >

inline  void                    DEVICE_MANAGER::set( const T& value ) const

{

    for( auto* device : devices )

    {

        if( device->device_type == DEVICE_TYPE::sensor )

            ( (SENSOR< T >*)device )->set( value );

    }

}

///---------------------------------------------------------------------------------------


class                           GYRO : public SENSOR< POINT3D >

{

protected:

    virtual void                refresh()

    {

        value.x = (float)rand() / rand();

        value.y = (float)rand() / rand();

        value.z = (float)rand() / rand();

    }


public:

    CSTR                        GYRO( DEVICE_MANAGER* owner, const int counter )

        : SENSOR< POINT3D >( owner, std::string( "Gyrosensor_" ) +

                             std::to_string( counter ) )

    {}

};

///---------------------------------------------------------------------------------------


class                           ACCE : public SENSOR< POINT3D >

{

protected:

    virtual void                refresh()

    {

        value.x = (float)rand();

        value.y = (float)rand();

        value.z = (float)rand();

    }


public:

    CSTR                        ACCE( DEVICE_MANAGER* owner, const int counter )

        : SENSOR< POINT3D >( owner, std::string( "Accelerometer_" ) +

                             std::to_string( counter ) )

    {}

};


//----------------------------------------------------------------------------------------


inline  std::string             get_version_string( const int_pair& version )

{

    return  std::to_string( version.first ) + "." + std::to_string( version.second );

}


inline  std::string             get_dimension_string( const int_pair& dimension )

{

    return  std::to_string( dimension.first ) + "x" + std::to_string( dimension.second );

}


class                           SMART_PHONE

{

protected:

    DEVICE_MANAGER*             sensor_manager;


    virtual std::string         get_model_name() const = 0;

    virtual std::string         get_core_type() const = 0;

    virtual int                 get_core_speed_mhz() const = 0;

    virtual int                 get_core_count() const = 0;

    virtual int                 get_ram_size_gb() const = 0;

    virtual int                 get_flash_size_gb() const = 0;

    virtual std::string         get_ext_memory_type() const { return  "None"; }

    virtual int                 get_ext_memory_max_gb() const = 0;

    virtual std::string         get_os_type() const = 0;

    virtual int_pair            get_os_version() const = 0;

    virtual std::string         get_display_type() const = 0;

    virtual int_pair            get_display_matrix() const = 0;

    virtual int                 get_pixel_density_ppi() const = 0;

    virtual std::string         get_proof_type() const { return  "None"; }

    virtual int                 get_battery_cap_mah() const = 0;

    virtual std::string         get_removable_battery() const { return  "No"; }


public:

    CSTR                        SMART_PHONE()

    {

        sensor_manager = new DEVICE_MANAGER();

    }

    DSTR                       ~SMART_PHONE()

    {

        delete  sensor_manager;

    }


    void                        show_specification() const

    {

        using   namespace       std;


        cout << "Model              : " << get_model_name() << endl;

        cout << "Processor          : " << get_core_speed_mhz() / 1000.f << "GHz "

                                        << get_core_type() << endl;

        cout << "Core               : " << get_core_count() << endl;

        cout << "RAM                : " << get_ram_size_gb() << "GB" << endl;


        cout << "Int. storage       : " << get_flash_size_gb() << "GB" << endl;

        cout << "Ext. storage       : " << get_ext_memory_max_gb() << "GB" << endl;


        cout << "OS                 : " << get_os_type() << " "

                                        << get_version_string( get_os_version() ) << endl;

        cout << "Display            : " << get_display_type() << " ("

                                        << get_dimension_string( get_display_matrix() )

                                        << ")" << endl;

        cout << "Pixel density      : " << get_pixel_density_ppi() << " PPI" << endl;

        cout << "Water/Dust proof   : " << get_proof_type() << endl;

        cout << "Battery capacity   : " << get_battery_cap_mah() << "mAh" << endl;

        cout << "Removable battery  : " << get_removable_battery() << endl;


        cout << endl;

    }


    void                        show_sensor()

    {

        sensor_manager->show();

    }


    void                        refresh()

    {

        sensor_manager->refresh();

    }


    template< typename T >

    void                        set_sensor( const T& value )

    {

        sensor_manager->set( value );

    }

};


//---------------------------------------------------------------------------------------


class                           GALAXY_S5 : public SMART_PHONE

{

private:

    static  int                 counter;

    GYRO*                       gyro;

    ACCE*                       acce;

    const   int                 battery_cap;


protected:

    virtual std::string         get_model_name() const

    {

        return  "Samsung Galaxy S5";

    }

    virtual std::string         get_core_type() const

    {

        return  "Snapdragon 801";

    }

    virtual int                 get_core_speed_mhz() const

    {

        return  2500;

    }

    virtual int                 get_core_count() const

    {

        return  4;

    }

    virtual int                 get_ram_size_gb() const

    {

        return  2;

    }

    virtual int                 get_flash_size_gb() const

    {

        return  16;

    }

    virtual std::string         get_ext_memory_type() const

    {

        return  "microSD";

    }

    virtual int                 get_ext_memory_max_gb() const

    {

        return  128;

    }

    virtual std::string         get_os_type() const

    {

        return  "Android";

    }

    virtual int_pair            get_os_version() const

    {

        return  std::make_pair( 4, 4 );

    }

    virtual std::string         get_display_type() const

    {

        return  "5.1\" Super AMOLED Full HD";

    }

    virtual int_pair            get_display_matrix() const

    {

        return  std::make_pair( 1920, 1080 );

    }

    virtual int                 get_pixel_density_ppi() const

    {

        return  432;

    }

    virtual std::string         get_proof_type() const

    {

        return  "IP67";

    }

    virtual int                 get_battery_cap_mah() const

    {

        return  battery_cap;

    }

    virtual std::string         get_removable_battery() const

    {

        return  "Yes";

    }


public:

    CSTR                        GALAXY_S5( const int battery_cap = 2800 )

        : battery_cap( battery_cap )

    {

        gyro = new GYRO( sensor_manager, 0 );

        acce = new ACCE( sensor_manager, 0 );

    }

};


int                             GALAXY_S5::counter = 0;


//---------------------------------------------------------------------------------------


class                           HTC_M8 : public SMART_PHONE

{

private:

    static  int                 counter;

    GYRO*                       gyro;

    ACCE*                       acce;

    const int                   flash_size;


protected:

    virtual std::string         get_model_name() const

    {

        return  "HTC One (M8)";

    }

    virtual std::string         get_core_type() const

    {

        return  "Snapdragon 801";

    }

    virtual int                 get_core_speed_mhz() const

    {

        return  2500;

    }

    virtual int                 get_core_count() const

    {

        return  4;

    }

    virtual int                 get_ram_size_gb() const

    {

        return  2;

    }

    virtual int                 get_flash_size_gb() const

    {

        return  flash_size;

    }

    virtual std::string         get_ext_memory_type() const

    {

        return  "microSD (128GB)";

    }

    virtual int                 get_ext_memory_max_gb() const

    {

        return  128;

    }

    virtual std::string         get_os_type() const

    {

        return  "Android";

    }

    virtual int_pair            get_os_version() const

    {

        return  std::make_pair( 4, 4 );

    }

    virtual std::string         get_display_type() const

    {

        return  "5.0\" Super Clear LCD 3 Full HD";

    }

    virtual int_pair            get_display_matrix() const

    {

        return  std::make_pair( 1920, 1080 );

    }

    virtual int                 get_pixel_density_ppi() const

    {

        return  440;

    }

    virtual int                 get_battery_cap_mah() const

    {

        return  2600;

    }


public:

    CSTR                        HTC_M8( const int flash_size )

        : flash_size( flash_size )

    {

        gyro = new GYRO( sensor_manager, 0 );

        acce = new ACCE( sensor_manager, 0 );

    }

};


int                             HTC_M8::counter = 0;


//---------------------------------------------------------------------------------------


int main()

{

    SMART_PHONE*    phones[] { new GALAXY_S5, new HTC_M8( 32 ) };


    for( const auto* phone : phones )

        phone->show_specification();


    for( auto* phone : phones )

    {

        phone->refresh();

        phone->show_sensor();

        phone->set_sensor( POINT3D( 0, 0, 0 ) );

        phone->show_sensor();

    }

    getchar();

    return  0;

}

//---------------------------------------------------------------------------------------


http://ideone.com/AlsbxZ


센서 가지고 놀길래 에뮬레이터 만드는 기분으로 작성함.

귀찮다~~~~~~~~


삼성폰은 배터리 착탈식으로 배터리 사양업그레이드가 가능.

HTC 폰은 생성시(제조시) 32기가 지원 가능.


둘 다 각각 몇 대 제조 되었는지 추적가능~