#include <utility>

enum CLStatus {CLSTATUS_SUCCESS, CLSTATUS_INVALIDPROJECTIONTYPE};
enum CEPTType {CEPTFull, CEPTBrief};

struct From {
    CEPTType eType;
};
struct Has {
	struct data { 
       From xFull;
       int xBrief;
	} xData;
	CEPTType eType;
};
struct HasNot {
	struct data { 
       From xFull;
	} xData;
	CEPTType eType;
};
CLStatus Convert(From f, int& dest) {
    return CLSTATUS_SUCCESS;
}



//ANSWER GOES HERE:

template< class... >
using void_t = void;

template <class Obj, class ObjResult, class = void>
struct ConvertIfHasBrief {
  static auto Convert(Obj const &, ObjResult &) -> CLStatus  {
      return {};// dymmy value, not used
   }
};

template <class Obj, class ObjResult>
struct ConvertIfHasBrief <Obj, ObjResult,
                   void_t<decltype(std::declval<ObjResult>().xData.xBrief)>> {
  static auto Convert(Obj const &xFrom, ObjResult &xTo) {
    return ::Convert(xFrom, xTo.xData.xBrief);
  }
};



template< class Obj, class ObjResult>
CLStatus convertObjToResult( const Obj & xFrom, ObjResult & xTo )
{
    CLStatus eStatus = CLSTATUS_SUCCESS;
    switch ( xTo.eType )
    {
        case CEPTFull:
            xTo.xData.xFull = xFrom;
            break;
        case CEPTBrief:
                eStatus = ConvertIfHasBrief<Obj, ObjResult>::Convert(xFrom, xTo);
            break;
        default:
            eStatus = CLSTATUS_INVALIDPROJECTIONTYPE;
    }
    return eStatus;
}



// RUN THE TEST

#include <iostream>
int main() {
	Has has;
	HasNot has_not;
    std::cout << convertObjToResult(From{}, has);
    std::cout << convertObjToResult(From{}, has_not);
    
}