⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csieveatl.cpp

📁 The code for this article was written for version 1.0 of the Active Template Library (ATL). The cu
💻 CPP
字号:
// CSieveATL.cpp : Implementation of CSieveATLApp and DLL registration.

#include "stdafx.h"
#include "SieveATL.h"
#include "CSieveATL.h"

/////////////////////////////////////////////////////////////////////////////
//

STDMETHODIMP CSieveATL::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_ISieveATL,
	};

	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

// CSieveATL Constructor and destructor
CSieveATL::CSieveATL()
{
   m_af = 0;
   m_iMaxPrime = PRIME_MAX;
}

CSieveATL::~CSieveATL()
{
   m_iMaxPrime = 0;    // Just a place for breakpoints
}


// CSieveATL methods and properties
STDMETHODIMP CSieveATL::get_NextPrime(short *piVal)
{
    // Loop until we find a prime or exceed maximum
    m_iCur++;
    while (m_af[m_iCur]) {
    m_iCur++;
        // When maximum exceeded, return 0
        if (m_iCur > m_iMaxPrime) {
            *piVal = 0;
            return NOERROR;
        }
    }
    // Cancel multiples of this prime
    int i;
    for (i = m_iCur + m_iCur; i < m_iMaxPrime; i += m_iCur) {
        m_af[i] = 1;
    }
    // Count this prime and return it
    m_cPrime++;
    *piVal = m_iCur;
	return S_OK;
}

STDMETHODIMP CSieveATL::get_MaxPrime(short *piVal)
{
    *piVal = m_iMaxPrime;
	return S_OK;
}

STDMETHODIMP CSieveATL::put_MaxPrime(short iVal)
{
    if (iVal <= 0) {
        return Error(OLESTR("Invalid maximum"));
    }
    m_iMaxPrime = iVal;
	return S_OK;
}

STDMETHODIMP CSieveATL::get_Primes(short *piVal)
{
    *piVal = m_cPrime;
	return S_OK;
}

STDMETHODIMP CSieveATL::Reinitialize()
{
    if (m_af) {
        delete m_af;
    }
    m_af = new short[m_iMaxPrime];
    memset(m_af, 0, sizeof(short) * m_iMaxPrime);
    m_iCur = 1;
    m_cPrime = 0;
	return S_OK;
}

STDMETHODIMP CSieveATL::AllPrimes(LPSAFEARRAY *ppsa)
{
    int i;
    long c;
    short * af;
    SAFEARRAYBOUND asabound[1];
    // Validate array
    if (SafeArrayGetDim(*ppsa) != 1)
        goto AllPrimesError;
    if (SafeArrayGetLBound(*ppsa, 1, &c) != NOERROR)
        goto AllPrimesError;
    if (c != 0)
        goto AllPrimesError;
    if (SafeArrayGetUBound(*ppsa, 1, &c) != NOERROR)
        goto AllPrimesError;
    if (c > PRIME_MAX)
        goto AllPrimesError;
    if (SafeArrayGetElemsize(*ppsa) != sizeof(short))
        goto AllPrimesError;
    // Unlock direct access to data
    if (SafeArrayAccessData(*ppsa, (void **)&af) != NOERROR)
        goto AllPrimesError;

    // Maximum prime is the size of the array
    m_iMaxPrime = (short)c;
    m_cPrime = 0;
    // Sieve of Eratosthenes algorithm
    for (m_iCur = 2; m_iCur < m_iMaxPrime; m_iCur++) {
        if (!af[m_iCur]) {
            // Found a prime
            for (i = m_iCur + m_iCur; i < m_iMaxPrime;
                                      i += m_iCur) {
                af[i] = 1;  // Cancel its multiples
            }
            // Write prime into position in array, count it
            af[m_cPrime] = m_iCur;
            m_cPrime++;
        }
    }
    // Relock direct access to data
    if (SafeArrayUnaccessData(*ppsa) != NOERROR)
        goto AllPrimesError;

    // Resize to include only the data
    asabound[0].lLbound = 0;
    asabound[0].cElements = m_cPrime;
    if (SafeArrayRedim(*ppsa, asabound) != NOERROR)
        goto AllPrimesError;
    m_iCur = 1;
	return S_OK;

AllPrimesError:
    return Error(OLESTR("Invalid array"));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -