function x = exist( obj, workerIdxs )
%EXIST Check whether Composite is defined on worker
%   H = EXIST(C, WORKERIDX) returns true if the entry in Composite C has a
%   defined value on the worker with spmdIndex WORKERIDX, false otherwise.
%   In the general case where WORKERIDX is an array, the output H is an
%   array of the same size as WORKERIDX, and H(I) indicates whether the
%   Composite entry WORKERIDX(I) has a defined value.
%
%   EXIST(C) is equivalent to EXIST(C, 1:LENGTH(C)).
%
%   If EXIST(C, WORKERIDX) returns true, C(WORKERIDX) does not throw an error,
%   provided the values of C on those workers are serializable.
%
%   The function throws an error if:
%   - The worker indices are invalid.
%
%   Example:
%   % Check where the Composite entries are defined, and get all those values:
%   spmd
%      if rand() > 0.5
%          c = spmdIndex;
%      end
%   end
%   ind = exist(c);
%   cvals = c(ind);
    
% Copyright 2008 The MathWorks, Inc.

% True if we either have a valid key, or a client-side value.
    if nargin == 1
        workerIdxs = 1:length( obj );
    end
    
    workerIdxsV = workerIdxs(:);

    % Arg check - need a vector of integers between 1 and numel
    if islogical( workerIdxsV )
        if length( workerIdxsV ) <= length ( obj )
            % For logical exist - we cannot possibly reshape the output to match the
            % input, so default to a row vector

            workerIdxs  = find( workerIdxsV ); % convert logical -> indexes
            workerIdxsV = workerIdxs(:);       % Re-create the column
            workerIdxs  = workerIdxsV.';       % create the row for defining the output shape
        else
            error(message('parallel:lang:spmd:CompositeExistTooManyValues'));
        end
    elseif isnumeric( workerIdxsV )
        if all( workerIdxsV <= length( obj ) ) && ...
                all( workerIdxsV >= 1 ) && ...
                all( workerIdxsV == round( workerIdxsV ) )
            % ok
        else
            error(message('parallel:lang:spmd:CompositeExistIdxOutOfBounds', length( obj )));
        end
    else
        error(message('parallel:lang:spmd:CompositeExistIdxType'));
    end
    
    if ~obj.isResourceSetOpen()
        % Pool closed, exist is false everywhere
        x = false( size( workerIdxsV ) );
    elseif obj.ClientValueValid
        % Got a client value, so exist is true everywhere
        x = true( size( workerIdxsV ) );
    else
        % Must check by key
        gotKey = ~cellfun( @isempty, obj.KeyVector );
        x = gotKey( workerIdxsV );
    end
    % Massage the shape to match the input
    x = reshape( x, size( workerIdxs ) );
end
